summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authoryurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-16 14:12:53 +0000
committeryurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-16 14:12:53 +0000
commit48764c72b775bdc62aa43eedaea00ca01597e9ff (patch)
treee3f2e20b62de4fbd071b803d3590d9da765b7023 /chrome/renderer
parentc855113f01088a707fb7538f6c54e284635cc779 (diff)
downloadchromium_src-48764c72b775bdc62aa43eedaea00ca01597e9ff.zip
chromium_src-48764c72b775bdc62aa43eedaea00ca01597e9ff.tar.gz
chromium_src-48764c72b775bdc62aa43eedaea00ca01597e9ff.tar.bz2
Review URL: http://codereview.chromium.org/20405
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9855 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/render_view.cc29
-rw-r--r--chrome/renderer/render_view.h15
-rw-r--r--chrome/renderer/renderer.scons5
-rw-r--r--chrome/renderer/renderer.vcproj20
-rw-r--r--chrome/renderer/tools_agent.cc150
-rw-r--r--chrome/renderer/tools_agent.h63
-rw-r--r--chrome/renderer/tools_client.cc80
-rw-r--r--chrome/renderer/tools_client.h53
-rw-r--r--chrome/renderer/tools_messages.h21
9 files changed, 436 insertions, 0 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index a8adb2f..1fa3650 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -11,6 +11,7 @@
#include "base/command_line.h"
#include "base/gfx/png_encoder.h"
#include "base/gfx/native_widget_types.h"
+#include "base/process_util.h"
#include "base/string_piece.h"
#include "base/string_util.h"
#include "build/build_config.h"
@@ -25,6 +26,7 @@
#include "chrome/common/thumbnail_score.h"
#include "chrome/renderer/about_handler.h"
#include "chrome/renderer/debug_message_handler.h"
+#include "chrome/renderer/tools_client.h"
#include "chrome/renderer/localized_error.h"
#include "chrome/renderer/render_process.h"
#include "chrome/renderer/user_script_slave.h"
@@ -168,6 +170,9 @@ RenderView::RenderView(RenderThreadBase* render_thread)
method_factory_(this),
first_default_plugin_(NULL),
printed_document_width_(0),
+ tools_agent_(NULL),
+ enable_tools_client_(false),
+ tools_client_(NULL),
history_back_list_count_(0),
history_forward_list_count_(0),
disable_popup_blocking_(false),
@@ -196,6 +201,10 @@ RenderView::~RenderView() {
}
render_thread_->RemoveFilter(debug_message_handler_);
+ render_thread_->RemoveFilter(tools_agent_);
+ if (tools_client_.get()) {
+ render_thread_->RemoveFilter(tools_client_);
+ }
#ifdef CHROME_PERSONALIZATION
Personalization::CleanupRendererPersonalization(personalization_);
@@ -313,6 +322,9 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd,
debug_message_handler_ = new DebugMessageHandler(this);
render_thread_->AddFilter(debug_message_handler_);
+
+ tools_agent_ = new ToolsAgent(this);
+ render_thread_->AddFilter(tools_agent_);
}
void RenderView::OnMessageReceived(const IPC::Message& message) {
@@ -355,6 +367,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_SetUpToolsClient, OnSetUpToolsClient)
IPC_MESSAGE_HANDLER(ViewMsg_DownloadImage, OnDownloadImage)
IPC_MESSAGE_HANDLER(ViewMsg_ScriptEvalRequest, OnScriptEvalRequest)
IPC_MESSAGE_HANDLER(ViewMsg_AddMessageToConsole, OnAddMessageToConsole)
@@ -897,6 +910,10 @@ void RenderView::OnShowJavaScriptConsole() {
webview()->ShowJavaScriptConsole();
}
+void RenderView::OnSetUpToolsClient() {
+ enable_tools_client_ = true;
+}
+
void RenderView::OnStopFinding(bool clear_selection) {
WebView* view = webview();
if (!view)
@@ -1502,6 +1519,13 @@ void RenderView::BindDOMAutomationController(WebFrame* webframe) {
L"domAutomationController");
}
+void RenderView::CreateToolsClient() {
+ DCHECK(!tools_client_.get());
+ tools_client_ = new ToolsClient(this);
+ webview()->SetUpToolsProxy(tools_client_);
+ render_thread_->AddFilter(tools_client_);
+}
+
void RenderView::WindowObjectCleared(WebFrame* webframe) {
external_js_object_.set_render_view(this);
external_js_object_.BindToJavascript(webframe, L"external");
@@ -1517,6 +1541,11 @@ void RenderView::WindowObjectCleared(WebFrame* webframe) {
external_host_bindings_.set_routing_id(routing_id_);
external_host_bindings_.BindToJavascript(webframe, L"externalHost");
}
+ // TODO(yurys): we wouldn't need to check that tools_client_ is not set yet if
+ // WindowObjectCleared were not called several times recursively
+ if (enable_tools_client_ && !tools_client_.get()) {
+ CreateToolsClient();
+ }
#ifdef CHROME_PERSONALIZATION
Personalization::ConfigureRendererPersonalization(personalization_, this,
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 6cafaa6..64e0caa 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -22,6 +22,8 @@
#include "chrome/renderer/dom_ui_bindings.h"
#include "chrome/renderer/external_host_bindings.h"
#include "chrome/renderer/external_js_object.h"
+#include "chrome/renderer/tools_agent.h"
+#include "chrome/renderer/tools_client.h"
#include "chrome/renderer/render_widget.h"
#include "testing/gtest/include/gtest/gtest_prod.h"
#include "webkit/glue/console_message_level.h"
@@ -438,6 +440,7 @@ class RenderView : public RenderWidget,
void OnCopyImageAt(int x, int y);
void OnInspectElement(int x, int y);
void OnShowJavaScriptConsole();
+ void OnSetUpToolsClient();
void OnCancelDownload(int32 download_id);
void OnFind(const FindInPageRequest& request);
void OnZoom(int function);
@@ -551,6 +554,10 @@ class RenderView : public RenderWidget,
// information to the browser process.
void BindDOMAutomationController(WebFrame* webframe);
+ // Creates ToolsClient and sets up JavaScript bindings for developer tools UI
+ // that is going to be hosted by this RenderView.
+ void CreateToolsClient();
+
void set_opened_by_user_gesture(bool value) {
opened_by_user_gesture_ = value;
}
@@ -693,6 +700,14 @@ class RenderView : public RenderWidget,
scoped_refptr<DebugMessageHandler> debug_message_handler_;
+ // Provides access to this renderer from the remote Inspector UI.
+ scoped_refptr<ToolsAgent> tools_agent_;
+
+ // Whether this renderer will serve as Inspector UI.
+ bool enable_tools_client_;
+
+ scoped_refptr<ToolsClient> 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 4f5ba60..f1ed92f 100644
--- a/chrome/renderer/renderer.scons
+++ b/chrome/renderer/renderer.scons
@@ -79,6 +79,11 @@ input_files = ChromeFileList([
'renderer_glue.cc',
'renderer_main.cc',
'renderer_resources.h',
+ 'tools_agent.cc',
+ 'tools_agent.h',
+ 'tools_client.cc',
+ 'tools_client.h',
+ 'tools_messages.h',
'user_script_slave.cc',
'user_script_slave.h',
'visitedlink_slave.cc',
diff --git a/chrome/renderer/renderer.vcproj b/chrome/renderer/renderer.vcproj
index 7e50f8f..8a1dc13 100644
--- a/chrome/renderer/renderer.vcproj
+++ b/chrome/renderer/renderer.vcproj
@@ -310,6 +310,26 @@
>
</File>
<File
+ RelativePath=".\tools_agent.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\tools_agent.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tools_client.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\tools_client.h"
+ >
+ </File>
+ <File
+ RelativePath=".\tools_messages.h"
+ >
+ </File>
+ <File
RelativePath=".\user_script_slave.cc"
>
</File>
diff --git a/chrome/renderer/tools_agent.cc b/chrome/renderer/tools_agent.cc
new file mode 100644
index 0000000..2f3fe2c
--- /dev/null
+++ b/chrome/renderer/tools_agent.cc
@@ -0,0 +1,150 @@
+// 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/tools_agent.h"
+
+#include "chrome/common/render_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"
+
+ToolsAgent::ToolsAgent(RenderView* view)
+ : channel_(NULL),
+ debugger_(NULL),
+ view_(view),
+ view_loop_(MessageLoop::current()) {
+}
+
+ToolsAgent::~ToolsAgent() {
+ OnDebugDetach();
+}
+
+void ToolsAgent::Send(ToolsClientMessageType message_type,
+ const std::wstring& body) {
+ DCHECK(channel_);
+ view_->Send(new ViewHostMsg_ToolsClientMsg(
+ view_->routing_id(), message_type, body));
+}
+
+// IPC::ChannelProxy::MessageFilter overrides:
+void ToolsAgent::OnFilterAdded(IPC::Channel* channel) {
+ channel_ = channel;
+}
+
+void ToolsAgent::OnFilterRemoved() {
+ OnDebugDetach();
+ channel_ = NULL;
+}
+
+// Called on IO thread.
+bool ToolsAgent::OnMessageReceived(const IPC::Message& message) {
+ if (message.routing_id() != view_->routing_id())
+ return false;
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ToolsAgent, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_ToolsAgentMsg, OnToolsAgentMsg)
+ IPC_MESSAGE_UNHANDLED(handled = false);
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+// Called on IO thread.
+void ToolsAgent::OnToolsAgentMsg(int tools_message_type,
+ const std::wstring& body) {
+ view_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this,
+ &ToolsAgent::HandleMessageInRenderThread,
+ tools_message_type,
+ body));
+}
+
+void ToolsAgent::HandleMessageInRenderThread(
+ int tools_message_type, const std::wstring& body) {
+ DCHECK(MessageLoop::current() == view_loop_);
+
+ switch(tools_message_type) {
+ case TOOLS_AGENT_MSG_DEBUG_ATTACH:
+ OnDebugAttach();
+ break;
+ case TOOLS_AGENT_MSG_DEBUG_DETACH:
+ OnDebugDetach();
+ break;
+ case TOOLS_AGENT_MSG_DEBUG_BREAK:
+ OnDebugBreak(body == L"true");
+ break;
+ case TOOLS_AGENT_MSG_DEBUG_COMMAND:
+ OnCommand(body);
+ break;
+ default:
+ NOTREACHED() << "Unknown ToolsAgentMessageType: " << tools_message_type;
+ }
+}
+
+void ToolsAgent::DebuggerOutput(const std::wstring& out) {
+ Send(TOOLS_CLIENT_MSG_DEBUGGER_OUTPUT, out);
+}
+
+void ToolsAgent::EvaluateScript(const std::wstring& script) {
+ DCHECK(MessageLoop::current() == view_loop_);
+ // It's possible that this will get cleared out from under us.
+ view_->EvaluateScript(L"", script);
+}
+
+void ToolsAgent::OnDebugAttach() {
+ if (!debugger_) {
+ debugger_ = new DebuggerBridge(this);
+ }
+
+ // Run the actual debugger attach in the renderer as it uses V8 methods which
+ // must run in the V8 thread.
+ DCHECK(MessageLoop::current() == view_loop_);
+ debugger_->Attach();
+
+ Send(TOOLS_CLIENT_MSG_DID_DEBUG_ATTACH, L"");
+
+// 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 ToolsAgent::OnDebugDetach() {
+ 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 ToolsAgent::OnDebugBreak(bool force) {
+ // 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.
+ DCHECK(MessageLoop::current() == view_loop_);
+ if (force)
+ EvaluateScript(std::wstring(L"javascript:void(0)"));
+}
+
+void ToolsAgent::OnCommand(const std::wstring& cmd) {
+ 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/tools_agent.h b/chrome/renderer/tools_agent.h
new file mode 100644
index 0000000..41f988c
--- /dev/null
+++ b/chrome/renderer/tools_agent.h
@@ -0,0 +1,63 @@
+// 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_TOOLS_AGENT_H_
+#define CHROME_RENDERER_TOOLS_AGENT_H_
+
+#include "base/basictypes.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/ipc_channel_proxy.h"
+#include "chrome/renderer/tools_messages.h"
+#include "webkit/glue/debugger_bridge.h"
+
+class Message;
+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 ToolsAgent : public IPC::ChannelProxy::MessageFilter,
+ public DebuggerBridge::Delegate {
+ public:
+ // ToolsAgent is a field of the RenderView. The view is supposed to be alive
+ // at least until OnFilterRemoved method is called.
+ explicit ToolsAgent(RenderView* view);
+ virtual ~ToolsAgent();
+
+ private:
+ // Sends message to ToolsClient.
+ void Send(ToolsClientMessageType message_type, const std::wstring& body);
+
+ // IPC::ChannelProxy::MessageFilter overrides:
+ virtual void OnFilterAdded(IPC::Channel* channel);
+ virtual void OnFilterRemoved();
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ void OnToolsAgentMsg(int tools_message_type, const std::wstring& body);
+ void HandleMessageInRenderThread(int tools_message_type,
+ const std::wstring& body);
+
+ // 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);
+
+ void OnDebugAttach();
+ void OnDebugDetach();
+ void OnDebugBreak(bool force);
+ void OnCommand(const std::wstring& cmd);
+
+ IPC::Channel* channel_;
+ scoped_refptr<DebuggerBridge> debugger_;
+ RenderView* view_;
+ MessageLoop* view_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(ToolsAgent);
+};
+
+#endif // CHROME_RENDERER_TOOLS_AGENT_H_
diff --git a/chrome/renderer/tools_client.cc b/chrome/renderer/tools_client.cc
new file mode 100644
index 0000000..1c673dc
--- /dev/null
+++ b/chrome/renderer/tools_client.cc
@@ -0,0 +1,80 @@
+// 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/tools_client.h"
+
+#include "chrome/common/render_messages.h"
+#include "chrome/renderer/render_view.h"
+#include "webkit/glue/tools_proxy.h"
+
+ToolsClient::ToolsClient(RenderView* view)
+ : tools_ui_(NULL),
+ render_view_(view),
+ view_loop_(MessageLoop::current()) {
+}
+
+ToolsClient::~ToolsClient() {
+ tools_ui_ = NULL;
+}
+
+void ToolsClient::Send(ToolsAgentMessageType message_type,
+ const std::wstring& json_arg) {
+ render_view_->Send(new ViewHostMsg_ToolsAgentMsg(
+ render_view_->routing_id(), message_type, json_arg));
+}
+
+// IPC::ChannelProxy::MessageFilter overrides:
+bool ToolsClient::OnMessageReceived(const IPC::Message& message) {
+ if (message.routing_id() != render_view_->routing_id()) {
+ NOTREACHED();
+ return false;
+ }
+
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ToolsClient, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_ToolsClientMsg, OnToolsClientMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false);
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void ToolsClient::OnToolsClientMessage(int tools_message_type,
+ const std::wstring& body) {
+ view_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ this,
+ &ToolsClient::HandleMessageInRenderThread,
+ tools_message_type,
+ body));
+}
+
+void ToolsClient::HandleMessageInRenderThread(int tools_message_type,
+ const std::wstring& body) {
+ DCHECK(view_loop_ == MessageLoop::current());
+
+ switch(tools_message_type) {
+ case TOOLS_CLIENT_MSG_DID_DEBUG_ATTACH:
+ OnDidDebugAttach();
+ break;
+ default:
+ NOTREACHED() << "Unknown message type: " << tools_message_type;
+ }
+}
+
+void ToolsClient::OnDidDebugAttach() {
+ if (tools_ui_)
+ tools_ui_->OnDidDebugAttach();
+}
+
+// DebuggerProxy methods:
+void ToolsClient::SetToolsUI(ToolsUI* tools_ui) {
+ tools_ui_ = tools_ui;
+}
+
+void ToolsClient::DebugAttach() {
+ Send(TOOLS_AGENT_MSG_DEBUG_ATTACH, L"");
+}
+
+void ToolsClient::DebugDetach() {
+ Send(TOOLS_AGENT_MSG_DEBUG_DETACH, L"");
+}
diff --git a/chrome/renderer/tools_client.h b/chrome/renderer/tools_client.h
new file mode 100644
index 0000000..8aad3df
--- /dev/null
+++ b/chrome/renderer/tools_client.h
@@ -0,0 +1,53 @@
+// 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_TOOLS_CLIENT_H_
+#define CHROME_RENDERER_TOOLS_CLIENT_H_
+
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/ipc_channel_proxy.h"
+#include "chrome/renderer/tools_messages.h"
+#include "webkit/glue/tools_proxy.h"
+
+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 ToolsAgent object.
+class ToolsClient : public ToolsProxy,
+ public IPC::ChannelProxy::MessageFilter {
+ public:
+ explicit ToolsClient(RenderView* view);
+ virtual ~ToolsClient();
+
+ private:
+ // DebuggerProxy overrides
+ virtual void SetToolsUI(ToolsUI*);
+ virtual void DebugAttach();
+ virtual void DebugDetach();
+
+ void OnDidDebugAttach();
+
+ // Sends message to ToolsAgent.
+ void Send(ToolsAgentMessageType message_type, const std::wstring& json_arg);
+
+ // IPC::ChannelProxy::MessageFilter overrides:
+ virtual bool OnMessageReceived(const IPC::Message& message);
+
+ void OnToolsClientMessage(int tools_message_type, const std::wstring& body);
+ void HandleMessageInRenderThread(int tools_message_type,
+ const std::wstring& body);
+
+ ToolsUI* tools_ui_;
+ RenderView* render_view_;
+ MessageLoop* view_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(ToolsClient);
+};
+
+#endif // CHROME_RENDERER_TOOLS_CLIENT_H_
diff --git a/chrome/renderer/tools_messages.h b/chrome/renderer/tools_messages.h
new file mode 100644
index 0000000..c8b3884
--- /dev/null
+++ b/chrome/renderer/tools_messages.h
@@ -0,0 +1,21 @@
+// 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_TOOLS_MESSAGES_H_
+#define CHROME_RENDERER_TOOLS_MESSAGES_H_
+
+enum ToolsAgentMessageType {
+ TOOLS_AGENT_MSG_DEBUG_ATTACH = 0,
+ TOOLS_AGENT_MSG_DEBUG_BREAK,
+ TOOLS_AGENT_MSG_DEBUG_COMMAND,
+ TOOLS_AGENT_MSG_DEBUG_DETACH
+};
+
+enum ToolsClientMessageType {
+ TOOLS_CLIENT_MSG_ADD_MESSAGE_TO_CONSOLE = 0,
+ TOOLS_CLIENT_MSG_DEBUGGER_OUTPUT,
+ TOOLS_CLIENT_MSG_DID_DEBUG_ATTACH
+};
+
+#endif // CHROME_RENDERER_TOOLS_MESSAGES_H_