summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-17 00:51:35 +0000
committerpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-17 00:51:35 +0000
commita862471b184f63a6f39c854e3abe4c26fb1edd1c (patch)
tree15cb15bed9476f80cb7a7b2034e1539d38417055 /chrome/renderer
parent220d7100e2095b875c401e32c3aab2830d4405e0 (diff)
downloadchromium_src-a862471b184f63a6f39c854e3abe4c26fb1edd1c.zip
chromium_src-a862471b184f63a6f39c854e3abe4c26fb1edd1c.tar.gz
chromium_src-a862471b184f63a6f39c854e3abe4c26fb1edd1c.tar.bz2
DevTools: Make all devtools messages dispatch through debugger interrupt.
Review URL: http://codereview.chromium.org/73002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13910 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/devtools_agent.cc21
-rw-r--r--chrome/renderer/devtools_agent.h14
-rw-r--r--chrome/renderer/devtools_agent_filter.cc128
-rw-r--r--chrome/renderer/devtools_agent_filter.h25
-rw-r--r--chrome/renderer/render_thread.cc6
-rw-r--r--chrome/renderer/render_thread.h3
-rw-r--r--chrome/renderer/render_view.cc13
-rw-r--r--chrome/renderer/render_view.h4
8 files changed, 166 insertions, 48 deletions
diff --git a/chrome/renderer/devtools_agent.cc b/chrome/renderer/devtools_agent.cc
index 046b755..918bb73 100644
--- a/chrome/renderer/devtools_agent.cc
+++ b/chrome/renderer/devtools_agent.cc
@@ -9,19 +9,23 @@
#include "chrome/renderer/render_view.h"
#include "webkit/glue/webdevtoolsagent.h"
+// static
+std::map<int, DevToolsAgent*> DevToolsAgent::agent_for_routing_id_;
+
DevToolsAgent::DevToolsAgent(int routing_id, RenderView* view)
: routing_id_(routing_id),
view_(view) {
+ agent_for_routing_id_[routing_id] = this;
}
DevToolsAgent::~DevToolsAgent() {
+ agent_for_routing_id_.erase(routing_id_);
}
// Called on the Renderer thread.
bool DevToolsAgent::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(DevToolsAgent, message)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Attach, OnAttach)
IPC_MESSAGE_HANDLER(DevToolsAgentMsg_Detach, OnDetach)
IPC_MESSAGE_HANDLER(DevToolsAgentMsg_RpcMessage, OnRpcMessage)
IPC_MESSAGE_HANDLER(DevToolsAgentMsg_InspectElement, OnInspectElement)
@@ -37,11 +41,18 @@ void DevToolsAgent::SendMessageToClient(const std::string& raw_msg) {
view_->Send(m);
}
-void DevToolsAgent::OnAttach() {
- WebDevToolsAgent* web_agent = GetWebAgent();
- if (web_agent) {
- web_agent->Attach();
+int DevToolsAgent::GetHostId() {
+ return routing_id_;
+}
+
+// static
+DevToolsAgent* DevToolsAgent::FromHostId(int host_id) {
+ std::map<int, DevToolsAgent*>::iterator it =
+ agent_for_routing_id_.find(host_id);
+ if (it != agent_for_routing_id_.end()) {
+ return it->second;
}
+ return NULL;
}
void DevToolsAgent::OnDetach() {
diff --git a/chrome/renderer/devtools_agent.h b/chrome/renderer/devtools_agent.h
index 7d3c4a1..9f813a3 100644
--- a/chrome/renderer/devtools_agent.h
+++ b/chrome/renderer/devtools_agent.h
@@ -5,6 +5,7 @@
#ifndef CHROME_RENDERER_DEVTOOLS_AGENT_H_
#define CHROME_RENDERER_DEVTOOLS_AGENT_H_
+#include <map>
#include <string>
#include "webkit/glue/webdevtoolsagent_delegate.h"
@@ -30,15 +31,24 @@ class DevToolsAgent : public WebDevToolsAgentDelegate {
// WebDevToolsAgentDelegate implementation
virtual void SendMessageToClient(const std::string& raw_msg);
+ virtual int GetHostId();
+
+ // Returns agent instance for its host id.
+ static DevToolsAgent* FromHostId(int host_id);
+
+ RenderView* render_view() { return view_; }
- private:
WebDevToolsAgent* GetWebAgent();
- void OnAttach();
+ private:
+ friend class DevToolsAgentFilter;
+
void OnDetach();
void OnRpcMessage(const std::string& raw_msg);
void OnInspectElement(int x, int y);
+ static std::map<int, DevToolsAgent*> agent_for_routing_id_;
+
int routing_id_; // View routing id that we can access from IO thread.
RenderView* view_;
diff --git a/chrome/renderer/devtools_agent_filter.cc b/chrome/renderer/devtools_agent_filter.cc
index 9ecc2b4..ec7dd1c7 100644
--- a/chrome/renderer/devtools_agent_filter.cc
+++ b/chrome/renderer/devtools_agent_filter.cc
@@ -4,31 +4,135 @@
#include "chrome/renderer/devtools_agent_filter.h"
+#include "base/command_line.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/devtools_messages.h"
+#include "chrome/renderer/devtools_agent.h"
+#include "chrome/renderer/plugin_channel_host.h"
+#include "chrome/renderer/render_view.h"
#include "webkit/glue/webdevtoolsagent.h"
-DevToolsAgentFilter::DevToolsAgentFilter(WebDevToolsAgent* webdevtools_agent,
- int routing_id)
- : webdevtools_agent_(webdevtools_agent),
- routing_id_(routing_id) {
+namespace {
+
+class DebuggerMessage : public WebDevToolsAgent::Message {
+ public:
+ DebuggerMessage(int routing_id, const IPC::Message& message)
+ : routing_id_(routing_id),
+ message_(message) {
+ }
+
+ virtual void Dispatch() {
+ DevToolsAgent* agent = DevToolsAgent::FromHostId(routing_id_);
+ if (agent) {
+ agent->OnMessageReceived(message_);
+ }
+ }
+
+ private:
+ int routing_id_;
+ IPC::Message message_;
+ DISALLOW_COPY_AND_ASSIGN(DebuggerMessage);
+};
+
+} // namespace
+
+std::set<int> DevToolsAgentFilter::attached_routing_ids_;
+
+DevToolsAgentFilter::DevToolsAgentFilter()
+ : current_routing_id_(0) {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ devtools_enabled_ = command_line.HasSwitch(
+ switches::kEnableOutOfProcessDevTools);
}
DevToolsAgentFilter::~DevToolsAgentFilter() {
}
bool DevToolsAgentFilter::OnMessageReceived(const IPC::Message& message) {
- if (routing_id_ != message.routing_id()) {
+ if (!devtools_enabled_) {
+ return false;
+ }
+ if (message.type() < DevToolsAgentStart ||
+ message.type() >= DevToolsAgentEnd) {
return false;
}
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(DevToolsAgentFilter, message)
- IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebuggerCommand, OnDebuggerCommand)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
+ int routing_id = message.routing_id();
+
+ MessageLoop* view_loop = RenderThread::current()->message_loop();
+ if (attached_routing_ids_.find(routing_id) == attached_routing_ids_.end()) {
+ // Agent has not been scheduled for attachment yet.
+ // Schedule attach command, no matter which one is actually being
+ // dispatched.
+ view_loop->PostTask(FROM_HERE, NewRunnableMethod(
+ this,
+ &DevToolsAgentFilter::Attach,
+ message.routing_id()));
+ attached_routing_ids_.insert(routing_id);
+
+#if defined(OS_WIN)
+ // Disable plugin message routing.
+ PluginChannelHost::SetListening(false);
+#endif
+ }
+
+ // If this is attach request - we are done.
+ if (message.type() == DevToolsAgentMsg_Attach::ID) {
+ return true;
+ }
+
+ if (message.type() == DevToolsAgentMsg_Detach::ID) {
+ // We are about to schedule detach.
+ attached_routing_ids_.erase(routing_id);
+ if (attached_routing_ids_.size() == 0) {
+#if defined(OS_WIN)
+ // All the agents are scheduled for detach -> resume dispatching
+ // of plugin messages.
+ PluginChannelHost::SetListening(true);
+#endif
+ }
+ }
+
+ if (message.type() != DevToolsAgentMsg_DebuggerCommand::ID) {
+ // Dispatch everything except for command through the debugger interrupt.
+ DebuggerMessage* m = new DebuggerMessage(routing_id, message);
+ WebDevToolsAgent::ScheduleMessageDispatch(m);
+ view_loop->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &DevToolsAgentFilter::EvalNoop,
+ routing_id));
+ return true;
+ } else {
+ // Dispatch command directly from IO.
+ bool handled = true;
+ current_routing_id_ = routing_id;
+ IPC_BEGIN_MESSAGE_MAP(DevToolsAgentFilter, message)
+ IPC_MESSAGE_HANDLER(DevToolsAgentMsg_DebuggerCommand, OnDebuggerCommand)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+ }
+}
+
+void DevToolsAgentFilter::EvalNoop(int routing_id) {
+ DevToolsAgent* agent = DevToolsAgent::FromHostId(routing_id);
+ if (agent) {
+ agent->render_view()->EvaluateScript(L"", L"javascript:void(0)");
+ }
+}
+
+void DevToolsAgentFilter::Attach(int routing_id) {
+ DevToolsAgent* agent = DevToolsAgent::FromHostId(routing_id);
+ if (agent) {
+ WebDevToolsAgent* web_agent = agent->GetWebAgent();
+ if (web_agent) {
+ web_agent->Attach();
+ }
+ }
}
void DevToolsAgentFilter::OnDebuggerCommand(const std::string& command) {
- WebDevToolsAgent::ExecuteDebuggerCommand(command, webdevtools_agent_);
+ WebDevToolsAgent::ExecuteDebuggerCommand(command, current_routing_id_);
}
diff --git a/chrome/renderer/devtools_agent_filter.h b/chrome/renderer/devtools_agent_filter.h
index c784383..f97e4a3 100644
--- a/chrome/renderer/devtools_agent_filter.h
+++ b/chrome/renderer/devtools_agent_filter.h
@@ -5,6 +5,7 @@
#ifndef CHROME_RENDERER_DEVTOOLS_AGENT_FILTER_H_
#define CHROME_RENDERER_DEVTOOLS_AGENT_FILTER_H_
+#include <set>
#include <string>
#include "chrome/common/ipc_channel_proxy.h"
@@ -19,15 +20,8 @@ class WebDevToolsAgent;
// is being used from this communication agent on the IO thread.
class DevToolsAgentFilter : public IPC::ChannelProxy::MessageFilter {
public:
- // DevToolsAgentFilter is a field of the RenderView. The view is supposed
- // to remove this agent from the message filter list on IO thread before
- // dying.
- //
- // Note that the pointer to WebDevToolsAgent should never be dereferenced on
- // the IO thread because it is destroyed asynchronously on the render thread.
- // However the filter needs it to pass along with debugger command request
- // to WebDevToolsAgent::ExecuteDebuggerCommand static method.
- DevToolsAgentFilter(WebDevToolsAgent* webdevtools_agent, int routing_id);
+ // There is a single instance of this class instantiated by the RenderThread.
+ DevToolsAgentFilter();
virtual ~DevToolsAgentFilter();
private:
@@ -38,8 +32,17 @@ class DevToolsAgentFilter : public IPC::ChannelProxy::MessageFilter {
// handle debug messages even when v8 is stopped.
void OnDebuggerCommand(const std::string& command);
- WebDevToolsAgent* webdevtools_agent_;
- int routing_id_; // View routing id that we can access from IO thread.
+ // Evaluates noop to kick the debugger.
+ void EvalNoop(int routing_id);
+
+ // Attaches agent.
+ void Attach(int routing_id);
+
+ static std::set<int> attached_routing_ids_;
+
+ int current_routing_id_;
+
+ bool devtools_enabled_;
DISALLOW_COPY_AND_ASSIGN(DevToolsAgentFilter);
};
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 5c084bb..6582be7 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -25,6 +25,7 @@
#include "chrome/plugin/plugin_channel_base.h"
#include "webkit/glue/weburlrequest.h"
#endif
+#include "chrome/renderer/devtools_agent_filter.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/extensions/renderer_extension_bindings.h"
@@ -118,11 +119,14 @@ void RenderThread::Init() {
histogram_snapshots_.reset(new RendererHistogramSnapshots());
app_cache_dispatcher_.reset(new AppCacheDispatcher());
WebAppCacheContext::SetFactory(CreateAppCacheContextForRenderer);
+ devtools_agent_filter_ = new DevToolsAgentFilter();
+ AddFilter(devtools_agent_filter_.get());
}
void RenderThread::CleanUp() {
// Shutdown in reverse of the initialization order.
-
+ RemoveFilter(devtools_agent_filter_.get());
+ devtools_agent_filter_ = NULL;
WebAppCacheContext::SetFactory(NULL);
app_cache_dispatcher_.reset();
histogram_snapshots_.reset();
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 637c4c5..d57026e 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -16,6 +16,7 @@
#include "chrome/renderer/renderer_histogram_snapshots.h"
class AppCacheDispatcher;
+class DevToolsAgentFilter;
class FilePath;
class NotificationService;
class RenderDnsMaster;
@@ -154,6 +155,8 @@ class RenderThread : public RenderThreadBase,
scoped_ptr<AppCacheDispatcher> app_cache_dispatcher_;
+ scoped_refptr<DevToolsAgentFilter> devtools_agent_filter_;
+
DISALLOW_COPY_AND_ASSIGN(RenderThread);
};
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index c0b13f2..64d20d2 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -31,7 +31,6 @@
#include "chrome/renderer/audio_message_filter.h"
#include "chrome/renderer/debug_message_handler.h"
#include "chrome/renderer/devtools_agent.h"
-#include "chrome/renderer/devtools_agent_filter.h"
#include "chrome/renderer/devtools_client.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/localized_error.h"
@@ -191,7 +190,6 @@ RenderView::RenderView(RenderThreadBase* render_thread)
ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
first_default_plugin_(NULL),
devtools_agent_(NULL),
- devtools_agent_filter_(NULL),
devtools_client_(NULL),
history_back_list_count_(0),
history_forward_list_count_(0),
@@ -218,8 +216,6 @@ RenderView::~RenderView() {
}
render_thread_->RemoveFilter(debug_message_handler_);
- if (devtools_agent_filter_.get())
- render_thread_->RemoveFilter(devtools_agent_filter_);
render_thread_->RemoveFilter(audio_message_filter_);
#ifdef CHROME_PERSONALIZATION
@@ -316,11 +312,6 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd,
webwidget_ = WebView::Create(this, webkit_prefs);
- if (dev_tools_enabled)
- devtools_agent_filter_ = new DevToolsAgentFilter(
- webview()->GetWebDevToolsAgent(),
- routing_id);
-
#if defined(OS_LINUX)
// We have to enable ourselves as the editor delegate on linux so we can copy
// text selections to the X clipboard.
@@ -355,8 +346,6 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd,
debug_message_handler_ = new DebugMessageHandler(this);
render_thread_->AddFilter(debug_message_handler_);
- if (dev_tools_enabled)
- render_thread_->AddFilter(devtools_agent_filter_);
audio_message_filter_ = new AudioMessageFilter(routing_id_);
render_thread_->AddFilter(audio_message_filter_);
@@ -370,8 +359,6 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
// If this is developer tools renderer intercept tools messages first.
if (devtools_client_.get() && devtools_client_->OnMessageReceived(message))
return;
- if (devtools_agent_.get() && devtools_agent_->OnMessageReceived(message))
- return;
IPC_BEGIN_MESSAGE_MAP(RenderView, message)
IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index f6bd01b..cbdf711 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -47,7 +47,6 @@ class AudioMessageFilter;
class DictionaryValue;
class DebugMessageHandler;
class DevToolsAgent;
-class DevToolsAgentFilter;
class DevToolsClient;
class FilePath;
class GURL;
@@ -743,9 +742,6 @@ class RenderView : public RenderWidget,
// Provides access to this renderer from the remote Inspector UI.
scoped_ptr<DevToolsAgent> devtools_agent_;
- // Handles messages on the IO thread while Renderer is on breakpoint.
- scoped_refptr<DevToolsAgentFilter> devtools_agent_filter_;
-
// DevToolsClient for renderer hosting developer tools UI. It's NULL for other
// render views.
scoped_ptr<DevToolsClient> devtools_client_;