summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--webkit/glue/devtools/debugger_agent_impl.cc2
-rw-r--r--webkit/glue/devtools/debugger_agent_impl.h8
-rw-r--r--webkit/glue/devtools/debugger_agent_manager.cc43
-rw-r--r--webkit/glue/devtools/debugger_agent_manager.h13
-rw-r--r--webkit/glue/webdevtoolsagent.h17
-rw-r--r--webkit/glue/webdevtoolsagent_delegate.h3
-rw-r--r--webkit/glue/webdevtoolsagent_impl.cc12
-rw-r--r--webkit/glue/webdevtoolsagent_impl.h2
16 files changed, 240 insertions, 74 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_;
diff --git a/webkit/glue/devtools/debugger_agent_impl.cc b/webkit/glue/devtools/debugger_agent_impl.cc
index 299af72..88fc171 100644
--- a/webkit/glue/devtools/debugger_agent_impl.cc
+++ b/webkit/glue/devtools/debugger_agent_impl.cc
@@ -31,7 +31,7 @@ using WebCore::V8Proxy;
DebuggerAgentImpl::DebuggerAgentImpl(
WebViewImpl* web_view_impl,
DebuggerAgentDelegate* delegate,
- WebDevToolsAgent* webdevtools_agent)
+ WebDevToolsAgentImpl* webdevtools_agent)
: web_view_impl_(web_view_impl),
delegate_(delegate),
webdevtools_agent_(webdevtools_agent) {
diff --git a/webkit/glue/devtools/debugger_agent_impl.h b/webkit/glue/devtools/debugger_agent_impl.h
index 664d506..acce569 100644
--- a/webkit/glue/devtools/debugger_agent_impl.h
+++ b/webkit/glue/devtools/debugger_agent_impl.h
@@ -8,7 +8,7 @@
#include "v8.h"
#include "webkit/glue/devtools/debugger_agent.h"
-class WebDevToolsAgent;
+class WebDevToolsAgentImpl;
class WebViewImpl;
namespace WebCore {
@@ -22,7 +22,7 @@ class DebuggerAgentImpl : public DebuggerAgent {
public:
DebuggerAgentImpl(WebViewImpl* web_view_impl,
DebuggerAgentDelegate* delegate,
- WebDevToolsAgent* webdevtools_agent);
+ WebDevToolsAgentImpl* webdevtools_agent);
virtual ~DebuggerAgentImpl();
// Initializes dom agent with the given document.
@@ -42,13 +42,13 @@ class DebuggerAgentImpl : public DebuggerAgent {
const WebCore::String& json_args);
WebCore::Page* GetPage();
- WebDevToolsAgent* webdevtools_agent() { return webdevtools_agent_; };
+ WebDevToolsAgentImpl* webdevtools_agent() { return webdevtools_agent_; };
private:
v8::Persistent<v8::Context> context_;
WebViewImpl* web_view_impl_;
DebuggerAgentDelegate* delegate_;
- WebDevToolsAgent* webdevtools_agent_;
+ WebDevToolsAgentImpl* webdevtools_agent_;
DISALLOW_COPY_AND_ASSIGN(DebuggerAgentImpl);
};
diff --git a/webkit/glue/devtools/debugger_agent_manager.cc b/webkit/glue/devtools/debugger_agent_manager.cc
index 678c904..ef37b7d 100644
--- a/webkit/glue/devtools/debugger_agent_manager.cc
+++ b/webkit/glue/devtools/debugger_agent_manager.cc
@@ -15,6 +15,7 @@
#include "base/values.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
+#include "webkit/glue/webdevtoolsagent_impl.h"
#if USE(V8)
#include "v8/include/v8-debug.h"
@@ -32,6 +33,15 @@ void DebuggerAgentManager::V8DebugMessageHandler(const uint16_t* message,
#endif
}
+void DebuggerAgentManager::V8DebugHostDispatchHandler(
+ void* dispatch,
+ void* data) {
+ WebDevToolsAgent::Message* m =
+ reinterpret_cast<WebDevToolsAgent::Message*>(dispatch);
+ m->Dispatch();
+ delete m;
+}
+
// static
DebuggerAgentManager::AttachedAgentsSet*
DebuggerAgentManager::attached_agents_ = NULL;
@@ -45,6 +55,9 @@ void DebuggerAgentManager::DebugAttach(DebuggerAgentImpl* debugger_agent) {
&DebuggerAgentManager::V8DebugMessageHandler,
NULL, /* no additional data */
false /* don't create separate thread for sending debugger output */);
+ v8::Debug::SetHostDispatchHandler(
+ &DebuggerAgentManager::V8DebugHostDispatchHandler,
+ NULL /* no additional data */);
}
attached_agents_->add(debugger_agent);
#endif
@@ -61,6 +74,7 @@ void DebuggerAgentManager::DebugDetach(DebuggerAgentImpl* debugger_agent) {
attached_agents_->remove(debugger_agent);
if (attached_agents_->isEmpty()) {
v8::Debug::SetMessageHandler(NULL);
+ v8::Debug::SetHostDispatchHandler(NULL);
delete attached_agents_;
attached_agents_ = NULL;
}
@@ -126,8 +140,8 @@ bool DebuggerAgentManager::SendCommandResponse(DictionaryValue* response) {
return false;
}
- int agent_ptr;
- if (!request_seq->GetInteger(L"webdevtools_agent", &agent_ptr)) {
+ int caller_id;
+ if (!request_seq->GetInteger(L"caller_id", &caller_id)) {
NOTREACHED();
return false;
}
@@ -140,7 +154,7 @@ bool DebuggerAgentManager::SendCommandResponse(DictionaryValue* response) {
}
DebuggerAgentImpl* debugger_agent = FindDebuggerAgentForToolsAgent(
- reinterpret_cast<WebDevToolsAgent*>(agent_ptr));
+ caller_id);
if (!debugger_agent) {
return false;
}
@@ -155,15 +169,23 @@ bool DebuggerAgentManager::SendCommandResponse(DictionaryValue* response) {
// static
void DebuggerAgentManager::ExecuteDebuggerCommand(
const std::string& command,
- WebDevToolsAgent* webdevtools_agent) {
+ int caller_id) {
const std::string cmd = DebuggerAgentManager::ReplaceRequestSequenceId(
command,
- webdevtools_agent);
+ caller_id);
SendCommandToV8(UTF8ToWide(cmd));
}
// static
+void DebuggerAgentManager::ScheduleMessageDispatch(
+ WebDevToolsAgent::Message* message) {
+#if USE(V8)
+ v8::Debug::SendHostDispatch(message);
+#endif
+}
+
+// static
void DebuggerAgentManager::SendCommandToV8(const std::wstring& cmd) {
#if USE(V8)
v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.data()),
@@ -195,7 +217,7 @@ DebuggerAgentImpl* DebuggerAgentManager::FindAgentForCurrentV8Context() {
const std::string DebuggerAgentManager::ReplaceRequestSequenceId(
const std::string& request,
- WebDevToolsAgent* webdevtools_agent) {
+ int caller_id) {
OwnPtr<Value> message(JSONReader::Read(request,
false /* allow_trailing_comma */));
if (!message.get()) {
@@ -219,8 +241,7 @@ const std::string DebuggerAgentManager::ReplaceRequestSequenceId(
// TODO(yurys): get rid of this hack, handler pointer should be passed
// into v8::Debug::SendCommand along with the command.
- int agent_ptr = reinterpret_cast<int>(webdevtools_agent);
- new_seq.Set(L"webdevtools_agent", Value::CreateIntegerValue(agent_ptr));
+ new_seq.SetInteger(L"caller_id", caller_id);
// TODO(yurys): fix v8 parser so that it handle objects as ids correctly.
std::string new_seq_str;
@@ -232,13 +253,11 @@ const std::string DebuggerAgentManager::ReplaceRequestSequenceId(
return json;
}
-// Note that we cannot safely dereference 'webdevtools_agent' bacause the
-// referenced agent may already have been detached and destroyed.
DebuggerAgentImpl* DebuggerAgentManager::FindDebuggerAgentForToolsAgent(
- WebDevToolsAgent* webdevtools_agent) {
+ int caller_id) {
for (AttachedAgentsSet::iterator it = attached_agents_->begin();
it != attached_agents_->end(); ++it) {
- if ((*it)->webdevtools_agent() == webdevtools_agent) {
+ if ((*it)->webdevtools_agent()->host_id() == caller_id) {
return *it;
}
}
diff --git a/webkit/glue/devtools/debugger_agent_manager.h b/webkit/glue/devtools/debugger_agent_manager.h
index 39469b8..42f03cc 100644
--- a/webkit/glue/devtools/debugger_agent_manager.h
+++ b/webkit/glue/devtools/debugger_agent_manager.h
@@ -10,10 +10,10 @@
#include "base/basictypes.h"
#include "v8/include/v8-debug.h"
+#include "webkit/glue/webdevtoolsagent.h"
class DebuggerAgentImpl;
class DictionaryValue;
-class WebDevToolsAgent;
// There is single v8 instance per render process. Also there may be several
// RenderViews and consequently devtools agents in the process that want to talk
@@ -38,7 +38,11 @@ class DebuggerAgentManager {
static void DebugCommand(const std::string& command);
static void ExecuteDebuggerCommand(const std::string& command,
- WebDevToolsAgent* webdevtools_agent);
+ int caller_id);
+
+ // Requests that debugger makes a callback on the render thread while on
+ // breakpoint.
+ static void ScheduleMessageDispatch(WebDevToolsAgent::Message* message);
private:
DebuggerAgentManager();
@@ -47,17 +51,18 @@ class DebuggerAgentManager {
static void V8DebugMessageHandler(const uint16_t* message,
int length,
void* data);
+ static void V8DebugHostDispatchHandler(void* dispatch, void* data);
static void DebuggerOutput(const std::string& out);
static void SendCommandToV8(const std::wstring& cmd);
static bool SendCommandResponse(DictionaryValue* response);
static DebuggerAgentImpl* FindAgentForCurrentV8Context();
static DebuggerAgentImpl* FindDebuggerAgentForToolsAgent(
- WebDevToolsAgent* webdevtools_agent);
+ int caller_id);
static const std::string ReplaceRequestSequenceId(
const std::string& request,
- WebDevToolsAgent* webdevtools_agent);
+ int caller_id);
typedef HashSet<DebuggerAgentImpl*> AttachedAgentsSet;
static AttachedAgentsSet* attached_agents_;
diff --git a/webkit/glue/webdevtoolsagent.h b/webkit/glue/webdevtoolsagent.h
index 30b7b5d5..049964b 100644
--- a/webkit/glue/webdevtoolsagent.h
+++ b/webkit/glue/webdevtoolsagent.h
@@ -12,6 +12,15 @@
// direct and delegate Apis to the host.
class WebDevToolsAgent {
public:
+ class Message {
+ public:
+ Message() {}
+ virtual ~Message() {}
+ virtual void Dispatch() = 0;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Message);
+ };
+
WebDevToolsAgent() {}
virtual ~WebDevToolsAgent() {}
@@ -24,9 +33,13 @@ class WebDevToolsAgent {
virtual void InspectElement(int x, int y) = 0;
// Asynchronously executes debugger command in the render thread.
- // |webdevtools_agent| will be used for sending response.
+ // |caller_id| will be used for sending response.
static void ExecuteDebuggerCommand(const std::string& command,
- WebDevToolsAgent* webdevtools_agent);
+ int caller_id);
+
+ // Requests that debugger makes a callback on the render thread while on
+ // breakpoint. Takes ownership of message.
+ static void ScheduleMessageDispatch(Message* message);
private:
DISALLOW_COPY_AND_ASSIGN(WebDevToolsAgent);
diff --git a/webkit/glue/webdevtoolsagent_delegate.h b/webkit/glue/webdevtoolsagent_delegate.h
index d1305a3..4112e4f 100644
--- a/webkit/glue/webdevtoolsagent_delegate.h
+++ b/webkit/glue/webdevtoolsagent_delegate.h
@@ -15,6 +15,9 @@ class WebDevToolsAgentDelegate {
virtual void SendMessageToClient(const std::string& raw_msg) = 0;
+ // Returns the id of the entity hosting this agent.
+ virtual int GetHostId() = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(WebDevToolsAgentDelegate);
};
diff --git a/webkit/glue/webdevtoolsagent_impl.cc b/webkit/glue/webdevtoolsagent_impl.cc
index 5602f45..11c64764 100644
--- a/webkit/glue/webdevtoolsagent_impl.cc
+++ b/webkit/glue/webdevtoolsagent_impl.cc
@@ -41,7 +41,8 @@ static const size_t kMaxConsoleMessages = 200;
WebDevToolsAgentImpl::WebDevToolsAgentImpl(
WebViewImpl* web_view_impl,
WebDevToolsAgentDelegate* delegate)
- : delegate_(delegate),
+ : host_id_(delegate->GetHostId()),
+ delegate_(delegate),
web_view_impl_(web_view_impl),
document_(NULL),
attached_(false) {
@@ -246,6 +247,11 @@ void WebDevToolsAgentImpl::SendRpcMessage(const std::string& raw_msg) {
// static
void WebDevToolsAgent::ExecuteDebuggerCommand(
const std::string& command,
- WebDevToolsAgent* webdevtools_agent) {
- DebuggerAgentManager::ExecuteDebuggerCommand(command, webdevtools_agent);
+ int caller_id) {
+ DebuggerAgentManager::ExecuteDebuggerCommand(command, caller_id);
+}
+
+// static
+void WebDevToolsAgent::ScheduleMessageDispatch(Message* message) {
+ DebuggerAgentManager::ScheduleMessageDispatch(message);
}
diff --git a/webkit/glue/webdevtoolsagent_impl.h b/webkit/glue/webdevtoolsagent_impl.h
index 216bf9c..232e8e3 100644
--- a/webkit/glue/webdevtoolsagent_impl.h
+++ b/webkit/glue/webdevtoolsagent_impl.h
@@ -71,6 +71,7 @@ class WebDevToolsAgentImpl
const WebCore::String& source_id,
unsigned int line_no);
+ int host_id() { return host_id_; }
NetAgentImpl* net_agent_impl() { return net_agent_impl_.get(); }
private:
@@ -84,6 +85,7 @@ class WebDevToolsAgentImpl
WebCore::String source_id;
unsigned int line_no;
};
+ int host_id_;
WebDevToolsAgentDelegate* delegate_;
WebViewImpl* web_view_impl_;
WebCore::Document* document_;