summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-26 12:39:28 +0000
committeryurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-26 12:39:28 +0000
commitb2abac7f32280c9d8bd0fd0d23c5432701634807 (patch)
tree62adfb69a3a725900cbd812c006622287bbb7c75
parentb5df94ed369ac59a76e81fb8a13552cac449509f (diff)
downloadchromium_src-b2abac7f32280c9d8bd0fd0d23c5432701634807.zip
chromium_src-b2abac7f32280c9d8bd0fd0d23c5432701634807.tar.gz
chromium_src-b2abac7f32280c9d8bd0fd0d23c5432701634807.tar.bz2
DevToolsAgent provides IPC access to the inspected page from developer tools.
RenderView running developer tools front-end instantiates DevToolsClient that handles IPC communication with DevToolsAgent. All messages are wrapped and routed through browser process. darin: please look at changes related to messages handling in RenderView jam: please review handling of forwarded messages in DevToolsClient and DevToolsAgent. Review URL: http://codereview.chromium.org/21543 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10459 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/chrome.xcodeproj/project.pbxproj16
-rw-r--r--chrome/renderer/dev_tools_agent.cc143
-rw-r--r--chrome/renderer/dev_tools_agent.h69
-rw-r--r--chrome/renderer/dev_tools_client.cc41
-rw-r--r--chrome/renderer/dev_tools_client.h43
-rw-r--r--chrome/renderer/dev_tools_messages.h12
-rw-r--r--chrome/renderer/dev_tools_messages_internal.h79
-rw-r--r--chrome/renderer/render_view.cc18
-rw-r--r--chrome/renderer/render_view.h14
-rw-r--r--chrome/renderer/renderer.scons6
-rw-r--r--chrome/renderer/renderer.vcproj24
11 files changed, 465 insertions, 0 deletions
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj
index 2f2af3d..9550646 100644
--- a/chrome/chrome.xcodeproj/project.pbxproj
+++ b/chrome/chrome.xcodeproj/project.pbxproj
@@ -90,6 +90,7 @@
261AA15DB2FF0FA9B0E63ACF /* automation_provider.cc in Sources */ = {isa = PBXBuildFile; fileRef = E48FB9640EC4EA270052B72B /* automation_provider.cc */; };
2760C4346D6AB3AD94E9CF05 /* url_fixer_upper.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5D16EF40F2145C600861FAC /* url_fixer_upper.cc */; };
28283DBE4B6DB2B0F9893676 /* dns_master.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFA6D0E9D4981009A6919 /* dns_master.cc */; };
+ 29D0CE7BEF15AE6D5233BA6A /* dev_tools_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2F904214F0F0BA780D8DC4C9 /* dev_tools_client.cc */; };
2D70E0E2053C6C759EC97929 /* chrome_plugin_util.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFB950E9D4C9F009A6919 /* chrome_plugin_util.cc */; };
2DF2A9EB8AF96926EE9B6B02 /* ipc_logging.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBAE0E9D4C9F009A6919 /* ipc_logging.cc */; };
3257B6150A16A88F55E5AE34 /* bookmark_drop_info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 12F137DA942221A44BFA0967 /* bookmark_drop_info.cc */; };
@@ -134,6 +135,7 @@
3380A9D60F2FC8F6004EF74F /* render_dns_master.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D640CE10EAE86A500EBCFC0 /* render_dns_master.cc */; };
3380A9D70F2FC8F9004EF74F /* render_dns_master.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D640CE10EAE86A500EBCFC0 /* render_dns_master.cc */; };
34A17287EFE747DE84BAE6E6 /* session_restore.cc in Sources */ = {isa = PBXBuildFile; fileRef = C3F9577C67188A5A4E3A6E41 /* session_restore.cc */; };
+ 3569E82DB055CE4B8E329CCC /* dev_tools_agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = D792830F807C366EAB752D69 /* dev_tools_agent.cc */; };
36F859CE61900AFD2AB67A91 /* save_item.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BF9D80E9D48CE009A6919 /* save_item.cc */; };
3AEA44DB19C9D93B63D7A2E4 /* url_fetcher_protect.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0B7CC9C105E90E0665852528 /* url_fetcher_protect.cc */; };
406DFE278638D6132B21B2C9 /* url_pattern.cc in Sources */ = {isa = PBXBuildFile; fileRef = 6447F24FADC63E58A44DB762 /* url_pattern.cc */; };
@@ -1962,12 +1964,15 @@
0082A7520F16987A000AA0EF /* user_script_master.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = user_script_master.h; sourceTree = "<group>"; };
0114EE7E1097BDFBF94057E6 /* search_provider.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = search_provider.cc; path = browser/autocomplete/search_provider.cc; sourceTree = SOURCE_ROOT; };
05C9D404FC8116984CCCEDED /* base_session_service.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = base_session_service.cc; path = sessions/base_session_service.cc; sourceTree = "<group>"; };
+ 07FE4EE1A3A0636A63757967 /* dev_tools_agent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dev_tools_agent.h; sourceTree = "<group>"; };
0B7CC9C105E90E0665852528 /* url_fetcher_protect.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = url_fetcher_protect.cc; sourceTree = "<group>"; };
+ 0DF4243691A34E9B11373400 /* dev_tools_messages_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dev_tools_messages_internal.h; sourceTree = "<group>"; };
12F137DA942221A44BFA0967 /* bookmark_drop_info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bookmark_drop_info.cc; path = browser/bookmarks/bookmark_drop_info.cc; sourceTree = SOURCE_ROOT; };
1F43A7C85092C58AAF011F78 /* greasemonkey_api_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = greasemonkey_api_unittest.cc; path = extensions/greasemonkey_api_unittest.cc; sourceTree = "<group>"; };
269003C4E493789D82B6B0F9 /* history_publisher.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = history_publisher.cc; sourceTree = "<group>"; };
26D97CE692D919FEB1521E43 /* ssl_error_info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ssl_error_info.cc; path = ssl/ssl_error_info.cc; sourceTree = "<group>"; };
28AA584AB2ECFB33C7C7FD8A /* template_url_parser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = template_url_parser.cc; sourceTree = "<group>"; };
+ 2F904214F0F0BA780D8DC4C9 /* dev_tools_client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dev_tools_client.cc; sourceTree = "<group>"; };
331B93A90F3BF2B9008B1C46 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
331B93AB0F3BF2DA008B1C46 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
3380A6B50F2E9252004EF74F /* render_thread_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render_thread_unittest.cc; sourceTree = "<group>"; };
@@ -2545,6 +2550,7 @@
759B3A1B81E261598122B03B /* v8_unit_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = v8_unit_test.cc; sourceTree = "<group>"; };
778D7927798B7E3FAA498D3D /* url_fetcher.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = url_fetcher.cc; sourceTree = "<group>"; };
7849CCC221723C1BC14D6384 /* history_publisher_none.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = history_publisher_none.cc; sourceTree = "<group>"; };
+ 7F10273789D2D71620792788 /* dev_tools_messages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dev_tools_messages.h; sourceTree = "<group>"; };
8104B4AFD95DCA06B2F37551 /* chrome_paths_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chrome_paths_internal.h; sourceTree = "<group>"; };
824FC14E0F44C56A000299E5 /* sadtab.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = sadtab.png; path = theme/sadtab.png; sourceTree = "<group>"; };
824FC1540F44C59C000299E5 /* sad_tab_view.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = sad_tab_view.mm; sourceTree = "<group>"; };
@@ -2564,6 +2570,7 @@
82FA32750F3A537C00271C5A /* web_contents_view_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = web_contents_view_mac.mm; path = tab_contents/web_contents_view_mac.mm; sourceTree = "<group>"; };
82FA33440F3A7F6900271C5A /* render_widget_host_view_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = render_widget_host_view_mac.h; path = renderer_host/render_widget_host_view_mac.h; sourceTree = "<group>"; };
82FA33450F3A7F6900271C5A /* render_widget_host_view_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = render_widget_host_view_mac.mm; path = renderer_host/render_widget_host_view_mac.mm; sourceTree = "<group>"; };
+ 839AD6DF3CB6649E84A4A94E /* dev_tools_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dev_tools_client.h; sourceTree = "<group>"; };
844EA0720F3E0BC900B0EF26 /* debugger_host.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debugger_host.h; path = debugger/debugger_host.h; sourceTree = "<group>"; };
844EA0730F3E0BEA00B0EF26 /* debugger_contents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debugger_contents.h; path = debugger/debugger_contents.h; sourceTree = "<group>"; };
844EA0740F3E0C1000B0EF26 /* debugger_contents.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = debugger_contents.cc; path = debugger/debugger_contents.cc; sourceTree = "<group>"; };
@@ -2744,6 +2751,7 @@
CAA0BC4B0F54A8F7004DEE42 /* hunspell.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = hunspell.xcodeproj; path = chrome/third_party/hunspell/hunspell.xcodeproj; sourceTree = "<group>"; };
D3C3DAA911D390A33D06B0B0 /* history_url_provider.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = history_url_provider.cc; path = browser/autocomplete/history_url_provider.cc; sourceTree = SOURCE_ROOT; };
D74DA6A9031CAE292790BD5E /* file_descriptor_set_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_descriptor_set_unittest.cc; sourceTree = "<group>"; };
+ D792830F807C366EAB752D69 /* dev_tools_agent.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dev_tools_agent.cc; sourceTree = "<group>"; };
D941DBEFD8B8B537DE8A4DAE /* bookmark_storage.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bookmark_storage.cc; path = bookmarks/bookmark_storage.cc; sourceTree = "<group>"; };
E40CC5E10F2E348900708647 /* history_contents_provider.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = history_contents_provider.cc; path = autocomplete/history_contents_provider.cc; sourceTree = "<group>"; };
E40CC5E20F2E348900708647 /* history_contents_provider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = history_contents_provider.h; path = autocomplete/history_contents_provider.h; sourceTree = "<group>"; };
@@ -3227,6 +3235,12 @@
4D640CC00EAE868600EBCFC0 /* chrome_plugin_host.h */,
4D640CC10EAE868600EBCFC0 /* debug_message_handler.cc */,
4D640CC20EAE868600EBCFC0 /* debug_message_handler.h */,
+ D792830F807C366EAB752D69 /* dev_tools_agent.cc */,
+ 07FE4EE1A3A0636A63757967 /* dev_tools_agent.h */,
+ 2F904214F0F0BA780D8DC4C9 /* dev_tools_client.cc */,
+ 839AD6DF3CB6649E84A4A94E /* dev_tools_client.h */,
+ 7F10273789D2D71620792788 /* dev_tools_messages.h */,
+ 0DF4243691A34E9B11373400 /* dev_tools_messages_internal.h */,
4D640CC30EAE868600EBCFC0 /* dom_ui_bindings.cc */,
4D640CC40EAE868600EBCFC0 /* dom_ui_bindings.h */,
4D640CC50EAE868600EBCFC0 /* external_host_bindings.cc */,
@@ -5609,6 +5623,8 @@
3380A69B0F2E91AE004EF74F /* child_process.cc in Sources */,
3380A69F0F2E91E5004EF74F /* chrome_plugin_lib.cc in Sources */,
AB8963010F4E0907009CFFAC /* data_source_impl.cc in Sources */,
+ 3569E82DB055CE4B8E329CCC /* dev_tools_agent.cc in Sources */,
+ 29D0CE7BEF15AE6D5233BA6A /* dev_tools_client.cc in Sources */,
E45076D90F1538E4003BE099 /* dom_automation_controller.cc in Sources */,
E45076C90F1537F5003BE099 /* dom_ui_bindings.cc in Sources */,
E45076CB0F15380C003BE099 /* external_host_bindings.cc in Sources */,
diff --git a/chrome/renderer/dev_tools_agent.cc b/chrome/renderer/dev_tools_agent.cc
new file mode 100644
index 0000000..891e895
--- /dev/null
+++ b/chrome/renderer/dev_tools_agent.cc
@@ -0,0 +1,143 @@
+// 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/renderer/dev_tools_agent.h"
+
+#include "base/message_loop.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/dev_tools_messages.h"
+// TODO(yurys): remove this macros once plugins available on other platforms
+#if defined(OS_WIN)
+#include "chrome/renderer/plugin_channel_host.h"
+#endif // OS_WIN
+#include "chrome/renderer/render_process.h"
+#include "chrome/renderer/render_view.h"
+
+DevToolsAgent::DevToolsAgent(RenderView* view, MessageLoop* view_loop)
+ : debugger_(NULL),
+ view_(view),
+ view_loop_(view_loop),
+ channel_(NULL),
+ io_loop_(NULL) {
+}
+
+DevToolsAgent::~DevToolsAgent() {
+}
+
+void DevToolsAgent::Send(const IPC::Message& tools_client_message) {
+ // It's possible that this will get cleared out from under us.
+ MessageLoop* io_loop = io_loop_;
+ if (!io_loop)
+ return;
+
+ IPC::Message* m = new ViewHostMsg_ForwardToDevToolsClient(
+ view_->routing_id(),
+ tools_client_message);
+ io_loop->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &DevToolsAgent::SendFromIOThread, m));
+}
+
+void DevToolsAgent::SendFromIOThread(IPC::Message* message) {
+ if (channel_) {
+ channel_->Send(message);
+ } else {
+ delete message;
+ }
+}
+
+// Called on IO thread.
+void DevToolsAgent::OnFilterAdded(IPC::Channel* channel) {
+ io_loop_ = MessageLoop::current();
+ channel_ = channel;
+}
+
+// Called on IO thread.
+bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) {
+ DCHECK(MessageLoop::current() == io_loop_);
+
+ if (message.routing_id() != view_->routing_id())
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(DevToolsAgent, message)
+ IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugAttach, OnDebugAttach)
+ IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugDetach, OnDebugDetach)
+ IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugBreak, OnDebugBreak)
+ IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebugCommand, OnDebugCommand)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void DevToolsAgent::OnFilterRemoved() {
+ io_loop_ = NULL;
+ channel_ = NULL;
+}
+
+void DevToolsAgent::DebuggerOutput(const std::wstring& out) {
+ Send(DevToolsClientMsg_DebuggerOutput(out));
+}
+
+void DevToolsAgent::EvaluateScript(const std::wstring& script) {
+ DCHECK(MessageLoop::current() == view_loop_);
+ view_->EvaluateScript(L"", script);
+}
+
+void DevToolsAgent::OnDebugAttach() {
+ DCHECK(MessageLoop::current() == io_loop_);
+ if (!debugger_) {
+ debugger_ = new DebuggerBridge(this);
+ }
+
+ debugger_->Attach();
+
+ Send(DevToolsClientMsg_DidDebugAttach());
+
+ // TODO(yurys): remove this macros once plugins available on other platforms
+#if defined(OS_WIN)
+ // Tell the plugin host to stop accepting messages in order to avoid
+ // hangs while the renderer is paused.
+ // TODO(yurys): It might be an improvement to add more plumbing to do this
+ // when the renderer is actually paused vs. just the debugger being attached.
+ // http://code.google.com/p/chromium/issues/detail?id=7556
+ PluginChannelHost::SetListening(false);
+#endif // OS_WIN
+}
+
+void DevToolsAgent::OnDebugDetach() {
+ DCHECK(MessageLoop::current() == io_loop_);
+ if (debugger_)
+ debugger_->Detach();
+ // TODO(yurys): remove this macros once plugins available on other platforms
+#if defined(OS_WIN)
+ PluginChannelHost::SetListening(true);
+#endif // OS_WIN
+}
+
+void DevToolsAgent::OnDebugBreak(bool force) {
+ DCHECK(MessageLoop::current() == io_loop_);
+ // Set the debug break flag in the V8 engine.
+ debugger_->Break(force);
+
+ // If a forced break has been requested make sure that it will occour by
+ // running some JavaScript in the renderer.
+ if (force && view_loop_) {
+ view_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &DevToolsAgent::EvaluateScript,
+ std::wstring(L"javascript:void(0)")));
+ }
+}
+
+void DevToolsAgent::OnDebugCommand(const std::wstring& cmd) {
+ DCHECK(MessageLoop::current() == io_loop_);
+ if (!debugger_) {
+ NOTREACHED();
+ std::wstring msg =
+ StringPrintf(L"before attach, ignored command (%S)", cmd.c_str());
+ DebuggerOutput(msg);
+ } else {
+ debugger_->Command(cmd);
+ }
+}
+
diff --git a/chrome/renderer/dev_tools_agent.h b/chrome/renderer/dev_tools_agent.h
new file mode 100644
index 0000000..c8c749e
--- /dev/null
+++ b/chrome/renderer/dev_tools_agent.h
@@ -0,0 +1,69 @@
+// 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.
+
+#ifndef CHROME_RENDERER_DEV_TOOLS_AGENT_H_
+#define CHROME_RENDERER_DEV_TOOLS_AGENT_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/ipc_channel_proxy.h"
+#include "webkit/glue/debugger_bridge.h"
+
+class MessageLoop;
+class RenderView;
+
+// Inspected page end of communication channel between the render process of
+// the page being inspected and tools UI renderer process. All messages will
+// go through browser process. On the renderer side of the tools UI there's
+// a corresponding ToolsClient object.
+class DevToolsAgent : public IPC::ChannelProxy::MessageFilter,
+ public DebuggerBridge::Delegate {
+ public:
+ // DevToolsAgent is a field of the RenderView. The view is supposed to remove
+ // this agent from message filter list on IO thread before dying.
+ explicit DevToolsAgent(RenderView* view, MessageLoop* view_loop);
+ virtual ~DevToolsAgent();
+
+ private:
+ // Sends message to DevToolsClient. May be called on any thread.
+ void Send(const IPC::Message& tools_client_message);
+
+ // Sends message to DevToolsClient. Must be called on IO thread. Takes
+ // ownership of the message.
+ void SendFromIOThread(IPC::Message* message);
+
+ // IPC::ChannelProxy::MessageFilter overrides. Called on IO thread.
+ virtual void OnFilterAdded(IPC::Channel* channel);
+ virtual bool OnMessageReceived(const IPC::Message& message);
+ virtual void OnFilterRemoved();
+
+ // Debugger::Delegate callback method to handle debugger output.
+ void DebuggerOutput(const std::wstring& out);
+
+ // Evaluate javascript URL in the renderer
+ void EvaluateScript(const std::wstring& script);
+
+ // All these OnXXX methods will be executed in IO thread so that we can
+ // handle debug messages even when v8 is stopped.
+ void OnDebugAttach();
+ void OnDebugDetach();
+ void OnDebugBreak(bool force);
+ void OnDebugCommand(const std::wstring& cmd);
+
+ scoped_refptr<DebuggerBridge> debugger_;
+
+ RenderView* view_;
+ MessageLoop* view_loop_;
+
+ IPC::Channel* channel_;
+ MessageLoop* io_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsAgent);
+};
+
+#endif // CHROME_RENDERER_DEV_TOOLS_AGENT_H_
+
diff --git a/chrome/renderer/dev_tools_client.cc b/chrome/renderer/dev_tools_client.cc
new file mode 100644
index 0000000..6061c92
--- /dev/null
+++ b/chrome/renderer/dev_tools_client.cc
@@ -0,0 +1,41 @@
+// 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/renderer/dev_tools_client.h"
+
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/dev_tools_messages.h"
+#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/render_view.h"
+
+DevToolsClient::DevToolsClient(RenderView* view)
+ : render_view_(view) {
+}
+
+DevToolsClient::~DevToolsClient() {
+}
+
+void DevToolsClient::Send(const IPC::Message& tools_agent_message) {
+ render_view_->Send(new ViewHostMsg_ForwardToDevToolsAgent(
+ render_view_->routing_id(),
+ tools_agent_message));
+}
+
+bool DevToolsClient::OnMessageReceived(const IPC::Message& message) {
+ DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(DevToolsClient, message)
+ IPC_MESSAGE_HANDLER(DevToolsClientMsg_DidDebugAttach, DidDebugAttach)
+ IPC_MESSAGE_UNHANDLED(handled = false);
+ IPC_END_MESSAGE_MAP()
+
+ return handled;
+}
+
+void DevToolsClient::DidDebugAttach() {
+ DCHECK(RenderThread::current()->message_loop() == MessageLoop::current());
+ // TODO(yurys): delegate to JS frontend.
+}
+
diff --git a/chrome/renderer/dev_tools_client.h b/chrome/renderer/dev_tools_client.h
new file mode 100644
index 0000000..d3dfdf1
--- /dev/null
+++ b/chrome/renderer/dev_tools_client.h
@@ -0,0 +1,43 @@
+// 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.
+
+#ifndef CHROME_RENDERER_DEV_TOOLS_CLIENT_H_
+#define CHROME_RENDERER_DEV_TOOLS_CLIENT_H_
+
+#include "base/basictypes.h"
+
+namespace IPC {
+class Message;
+}
+class MessageLoop;
+class RenderView;
+
+// Developer tools UI end of communication channel between the render process of
+// the page being inspected and tools UI renderer process. All messages will
+// go through browser process. On the side of the inspected page there's
+// corresponding DevToolsAgent object.
+// TODO(yurys): now the client is almost empty later it will delegate calls to
+// code in glue
+class DevToolsClient {
+ public:
+ explicit DevToolsClient(RenderView* view);
+ virtual ~DevToolsClient();
+
+ // Called to possibly handle the incoming IPC message. Returns true if
+ // handled. Called in render thread.
+ bool OnMessageReceived(const IPC::Message& message);
+
+ private:
+ void DidDebugAttach();
+
+ // Sends message to DevToolsAgent.
+ void Send(const IPC::Message& tools_agent_message);
+
+ RenderView* render_view_; // host render view
+
+ DISALLOW_COPY_AND_ASSIGN(DevToolsClient);
+};
+
+#endif // CHROME_RENDERER_DEV_TOOLS_CLIENT_H_
+
diff --git a/chrome/renderer/dev_tools_messages.h b/chrome/renderer/dev_tools_messages.h
new file mode 100644
index 0000000..9225c2e
--- /dev/null
+++ b/chrome/renderer/dev_tools_messages.h
@@ -0,0 +1,12 @@
+// 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.
+
+#ifndef CHROME_RENDERER_DEV_TOOLS_MESSAGES_H_
+#define CHROME_RENDERER_DEV_TOOLS_MESSAGES_H_
+
+#define MESSAGES_INTERNAL_FILE "chrome/renderer/dev_tools_messages_internal.h"
+#include "chrome/common/ipc_message_macros.h"
+
+#endif // CHROME_RENDERER_DEV_TOOLS_MESSAGES_H_
+
diff --git a/chrome/renderer/dev_tools_messages_internal.h b/chrome/renderer/dev_tools_messages_internal.h
new file mode 100644
index 0000000..9a1f8b5
--- /dev/null
+++ b/chrome/renderer/dev_tools_messages_internal.h
@@ -0,0 +1,79 @@
+// 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.
+
+// This header is meant to be included in multiple passes, hence no traditional
+// header guard.
+// See ipc_message_macros.h for explanation of the macros and passes.
+
+// Developer tools consist of the following parts:
+//
+// DevToolsAgent lives in the renderer of an inspected page and provides access
+// to the pages resources, DOM, v8 etc. by means of IPC messages.
+//
+// DevToolsClient is a thin delegate that lives in the tools front-end renderer
+// and converts IPC messages to frontend method calls and allows the frontend
+// to send messages to the DevToolsAgent.
+//
+// All the messages are routed through browser process.
+//
+// Chain of communication between the components may be described by the
+// following diagram:
+// ----------------------------
+// | (tools frontend |
+// | renderer process) |
+// | | --------------------
+// |tools <--> DevToolsClient+<-- IPC -->+ (browser process) |
+// |frontend | | |
+// ---------------------------- ---------+----------
+// ^
+// |
+// IPC
+// |
+// v
+// --------------------------+--------
+// | inspected page <--> DevToolsAgent |
+// | |
+// | (inspected page renderer process) |
+// -----------------------------------
+//
+// This file describes developer tools message types.
+
+#include "chrome/common/ipc_message_macros.h"
+
+// These are messages sent from DevToolsAgent to DevToolsClient through the
+// browser.
+IPC_BEGIN_MESSAGES(DevToolsClient)
+
+ // Response message for DevToolsAgentMsg_DebugAttach.
+ IPC_MESSAGE_CONTROL0(DevToolsClientMsg_DidDebugAttach)
+
+ // WebKit and JavaScript error messages to log to the console
+ // or debugger UI.
+ IPC_MESSAGE_CONTROL1(DevToolsClientMsg_DebuggerOutput,
+ std::wstring /* msg */)
+
+IPC_END_MESSAGES(DevToolsClient)
+
+
+//-----------------------------------------------------------------------------
+// These are messages sent from DevToolsClient to DevToolsAgent through the
+// browser.
+IPC_BEGIN_MESSAGES(DevToolsAgent)
+
+ // Initialize the V8 debugger in the renderer.
+ IPC_MESSAGE_CONTROL0(DevToolsAgentMsg_DebugAttach)
+
+ // Shutdown the V8 debugger in the renderer.
+ IPC_MESSAGE_CONTROL0(DevToolsAgentMsg_DebugDetach)
+
+ // Break V8 execution.
+ IPC_MESSAGE_CONTROL1(DevToolsAgentMsg_DebugBreak,
+ bool /* force */)
+
+ // Send a command to the V8 debugger.
+ IPC_MESSAGE_CONTROL1(DevToolsAgentMsg_DebugCommand,
+ std::wstring /* cmd */)
+
+IPC_END_MESSAGES(DevToolsAgent)
+
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 8621085..91efbf4 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -26,6 +26,8 @@
#include "chrome/common/url_constants.h"
#include "chrome/renderer/about_handler.h"
#include "chrome/renderer/debug_message_handler.h"
+#include "chrome/renderer/dev_tools_agent.h"
+#include "chrome/renderer/dev_tools_client.h"
#include "chrome/renderer/localized_error.h"
#include "chrome/renderer/media/audio_renderer_impl.h"
#include "chrome/renderer/render_process.h"
@@ -169,6 +171,8 @@ RenderView::RenderView(RenderThreadBase* render_thread)
method_factory_(this),
first_default_plugin_(NULL),
printed_document_width_(0),
+ dev_tools_agent_(NULL),
+ dev_tools_client_(NULL),
history_back_list_count_(0),
history_forward_list_count_(0),
disable_popup_blocking_(false),
@@ -197,6 +201,7 @@ RenderView::~RenderView() {
}
render_thread_->RemoveFilter(debug_message_handler_);
+ render_thread_->RemoveFilter(dev_tools_agent_);
#ifdef CHROME_PERSONALIZATION
Personalization::CleanupRendererPersonalization(personalization_);
@@ -314,6 +319,9 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd,
debug_message_handler_ = new DebugMessageHandler(this);
render_thread_->AddFilter(debug_message_handler_);
+
+ dev_tools_agent_ = new DevToolsAgent(this, MessageLoop::current());
+ render_thread_->AddFilter(dev_tools_agent_);
}
void RenderView::OnMessageReceived(const IPC::Message& message) {
@@ -333,6 +341,10 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
if (resource_dispatcher_->OnMessageReceived(message))
return;
+ // If this is developer tools renderer intercept tools messages first.
+ if (dev_tools_client_.get() && dev_tools_client_->OnMessageReceived(message))
+ return;
+
IPC_BEGIN_MESSAGE_MAP(RenderView, message)
IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)
IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
@@ -356,6 +368,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_SetPageEncoding, OnSetPageEncoding)
IPC_MESSAGE_HANDLER(ViewMsg_InspectElement, OnInspectElement)
IPC_MESSAGE_HANDLER(ViewMsg_ShowJavaScriptConsole, OnShowJavaScriptConsole)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetupDevToolsClient, OnSetupDevToolsClient)
IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
@@ -904,6 +917,11 @@ void RenderView::OnShowJavaScriptConsole() {
webview()->ShowJavaScriptConsole();
}
+void RenderView::OnSetupDevToolsClient() {
+ DCHECK(!dev_tools_client_.get());
+ dev_tools_client_.reset(new DevToolsClient(this));
+}
+
void RenderView::OnStopFinding(bool clear_selection) {
WebView* view = webview();
if (!view)
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 6202f7a..b4a39bb 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -44,6 +44,8 @@
class AudioRendererImpl;
class DictionaryValue;
class DebugMessageHandler;
+class DevToolsAgent;
+class DevToolsClient;
class FilePath;
class GlueAccessibility;
class GURL;
@@ -460,6 +462,7 @@ class RenderView : public RenderWidget,
void OnCopyImageAt(int x, int y);
void OnInspectElement(int x, int y);
void OnShowJavaScriptConsole();
+ void OnSetupDevToolsClient();
void OnCancelDownload(int32 download_id);
void OnFind(const FindInPageRequest& request);
void OnZoom(int function);
@@ -590,6 +593,10 @@ class RenderView : public RenderWidget,
// information to the browser process.
void BindDOMAutomationController(WebFrame* webframe);
+ // Creates DevToolsClient and sets up JavaScript bindings for developer tools
+ // UI that is going to be hosted by this RenderView.
+ void CreateDevToolsClient();
+
void set_opened_by_user_gesture(bool value) {
opened_by_user_gesture_ = value;
}
@@ -732,6 +739,13 @@ class RenderView : public RenderWidget,
scoped_refptr<DebugMessageHandler> debug_message_handler_;
+ // Provides access to this renderer from the remote Inspector UI.
+ scoped_refptr<DevToolsAgent> dev_tools_agent_;
+
+ // DevToolsClient for renderer hosting developer tools UI. It's NULL for other
+ // render views.
+ scoped_ptr<DevToolsClient> dev_tools_client_;
+
scoped_ptr<WebFileChooserCallback> file_chooser_;
int history_back_list_count_;
diff --git a/chrome/renderer/renderer.scons b/chrome/renderer/renderer.scons
index 2522959..85bfde1 100644
--- a/chrome/renderer/renderer.scons
+++ b/chrome/renderer/renderer.scons
@@ -66,6 +66,12 @@ input_files = ChromeFileList([
'chrome_plugin_host.h',
'debug_message_handler.cc',
'debug_message_handler.h',
+ 'dev_tools_agent.cc',
+ 'dev_tools_agent.h',
+ 'dev_tools_client.cc',
+ 'dev_tools_client.h',
+ 'dev_tools_messages.h',
+ 'dev_tools_messages_internal.h',
'dom_ui_bindings.cc',
'dom_ui_bindings.h',
'external_host_bindings.cc',
diff --git a/chrome/renderer/renderer.vcproj b/chrome/renderer/renderer.vcproj
index caa5e20..8e81aac 100644
--- a/chrome/renderer/renderer.vcproj
+++ b/chrome/renderer/renderer.vcproj
@@ -206,6 +206,30 @@
>
</File>
<File
+ RelativePath=".\dev_tools_agent.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\dev_tools_agent.h"
+ >
+ </File>
+ <File
+ RelativePath=".\dev_tools_client.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\dev_tools_client.h"
+ >
+ </File>
+ <File
+ RelativePath=".\dev_tools_messages.h"
+ >
+ </File>
+ <File
+ RelativePath=".\dev_tools_messages_internal.h"
+ >
+ </File>
+ <File
RelativePath=".\dom_ui_bindings.cc"
>
</File>