summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/devtools/debugger_agent_impl.cc14
-rw-r--r--webkit/glue/devtools/debugger_agent_impl.h13
-rw-r--r--webkit/glue/devtools/debugger_agent_manager.cc165
-rw-r--r--webkit/glue/devtools/debugger_agent_manager.h17
-rw-r--r--webkit/glue/webdevtoolsagent.h4
-rw-r--r--webkit/glue/webdevtoolsagent_impl.cc10
6 files changed, 205 insertions, 18 deletions
diff --git a/webkit/glue/devtools/debugger_agent_impl.cc b/webkit/glue/devtools/debugger_agent_impl.cc
index 6838d5b..dc475ab 100644
--- a/webkit/glue/devtools/debugger_agent_impl.cc
+++ b/webkit/glue/devtools/debugger_agent_impl.cc
@@ -16,6 +16,7 @@
#include "webkit/glue/devtools/debugger_agent_manager.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webkit_glue.h"
+#include "webkit/glue/webview_impl.h"
using WebCore::Document;
using WebCore::Node;
@@ -23,8 +24,13 @@ using WebCore::String;
using WebCore::V8ClassIndex;
using WebCore::V8Proxy;
-DebuggerAgentImpl::DebuggerAgentImpl(DebuggerAgentDelegate* delegate)
- : delegate_(delegate) {
+DebuggerAgentImpl::DebuggerAgentImpl(
+ WebViewImpl* web_view_impl,
+ DebuggerAgentDelegate* delegate,
+ WebDevToolsAgent* webdevtools_agent)
+ : web_view_impl_(web_view_impl),
+ delegate_(delegate),
+ webdevtools_agent_(webdevtools_agent) {
DebuggerAgentManager::DebugAttach(this);
}
@@ -86,3 +92,7 @@ String DebuggerAgentImpl::ExecuteUtilityFunction(
v8::Handle<v8::String> res_json = v8::Handle<v8::String>::Cast(res_obj);
return WebCore::toWebCoreString(res_json);
}
+
+WebCore::Page* DebuggerAgentImpl::GetPage() {
+ return web_view_impl_->page();
+}
diff --git a/webkit/glue/devtools/debugger_agent_impl.h b/webkit/glue/devtools/debugger_agent_impl.h
index aa0db70..664d506 100644
--- a/webkit/glue/devtools/debugger_agent_impl.h
+++ b/webkit/glue/devtools/debugger_agent_impl.h
@@ -8,15 +8,21 @@
#include "v8.h"
#include "webkit/glue/devtools/debugger_agent.h"
+class WebDevToolsAgent;
+class WebViewImpl;
+
namespace WebCore {
class Document;
class Node;
+class Page;
class String;
}
class DebuggerAgentImpl : public DebuggerAgent {
public:
- explicit DebuggerAgentImpl(DebuggerAgentDelegate* delegate);
+ DebuggerAgentImpl(WebViewImpl* web_view_impl,
+ DebuggerAgentDelegate* delegate,
+ WebDevToolsAgent* webdevtools_agent);
virtual ~DebuggerAgentImpl();
// Initializes dom agent with the given document.
@@ -35,9 +41,14 @@ class DebuggerAgentImpl : public DebuggerAgent {
WebCore::Node* node,
const WebCore::String& json_args);
+ WebCore::Page* GetPage();
+ WebDevToolsAgent* webdevtools_agent() { return webdevtools_agent_; };
+
private:
v8::Persistent<v8::Context> context_;
+ WebViewImpl* web_view_impl_;
DebuggerAgentDelegate* delegate_;
+ WebDevToolsAgent* 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 d37c8d3..678c904 100644
--- a/webkit/glue/devtools/debugger_agent_manager.cc
+++ b/webkit/glue/devtools/debugger_agent_manager.cc
@@ -4,10 +4,15 @@
#include "config.h"
+#include "Frame.h"
+#include "v8_proxy.h"
#include <wtf/HashSet.h>
#undef LOG
+#include "base/json_reader.h"
+#include "base/json_writer.h"
#include "base/string_util.h"
+#include "base/values.h"
#include "webkit/glue/devtools/debugger_agent_impl.h"
#include "webkit/glue/devtools/debugger_agent_manager.h"
@@ -15,6 +20,7 @@
#include "v8/include/v8-debug.h"
#endif
+
// static
void DebuggerAgentManager::V8DebugMessageHandler(const uint16_t* message,
int length,
@@ -71,29 +77,170 @@ void DebuggerAgentManager::DebugBreak(DebuggerAgentImpl* debugger_agent) {
// static
void DebuggerAgentManager::DebuggerOutput(const std::string& out) {
- DebuggerAgentImpl* agent = GetAgentForCurrentV8Context();
+ OwnPtr<Value> response(JSONReader::Read(out,
+ false /* allow_trailing_comma */));
+ if (!response.get()) {
+ NOTREACHED();
+ return;
+ }
+ if (!response->IsType(Value::TYPE_DICTIONARY)) {
+ NOTREACHED();
+ return;
+ }
+ DictionaryValue* m = static_cast<DictionaryValue*>(response.get());
+
+ std::string type;
+ if (!m->GetString(L"type", &type)) {
+ NOTREACHED();
+ return;
+ }
+
+ // Agent that should be used for sending command response is determined based
+ // on the 'request_seq' field in the response body.
+ if (type == "response") {
+ SendCommandResponse(m);
+ return;
+ }
+
+ // Agent that should be used for sending events is determined based
+ // on the active Frame.
+ DebuggerAgentImpl* agent = FindAgentForCurrentV8Context();
if (!agent) {
+ // Autocontinue execution on break and exception events if there is no
+ // handler.
+ std::wstring continue_cmd(
+ L"{\"seq\":1,\"type\":\"request\",\"command\":\"continue\"}");
+ SendCommandToV8(continue_cmd);
return;
}
agent->DebuggerOutput(out);
}
// static
-void DebuggerAgentManager::ExecuteDebuggerCommand(const std::string& command) {
+bool DebuggerAgentManager::SendCommandResponse(DictionaryValue* response) {
+ // TODO(yurys): there is a bug in v8 which converts original string seq into
+ // a json dictinary.
+ DictionaryValue* request_seq;
+ if (!response->GetDictionary(L"request_seq", &request_seq)) {
+ NOTREACHED();
+ return false;
+ }
+
+ int agent_ptr;
+ if (!request_seq->GetInteger(L"webdevtools_agent", &agent_ptr)) {
+ NOTREACHED();
+ return false;
+ }
+
+ Value* original_request_seq;
+ if (request_seq->Get(L"request_seq", &original_request_seq)) {
+ response->Set(L"request_seq", original_request_seq->DeepCopy());
+ } else {
+ response->Remove(L"request_seq", NULL /* out_value */);
+ }
+
+ DebuggerAgentImpl* debugger_agent = FindDebuggerAgentForToolsAgent(
+ reinterpret_cast<WebDevToolsAgent*>(agent_ptr));
+ if (!debugger_agent) {
+ return false;
+ }
+
+ std::string json;
+ JSONWriter::Write(response, false /* pretty_print */, &json);
+ debugger_agent->DebuggerOutput(json);
+ return true;
+}
+
+
+// static
+void DebuggerAgentManager::ExecuteDebuggerCommand(
+ const std::string& command,
+ WebDevToolsAgent* webdevtools_agent) {
+ const std::string cmd = DebuggerAgentManager::ReplaceRequestSequenceId(
+ command,
+ webdevtools_agent);
+
+ SendCommandToV8(UTF8ToWide(cmd));
+}
+
+// static
+void DebuggerAgentManager::SendCommandToV8(const std::wstring& cmd) {
#if USE(V8)
- std::wstring cmd_wstring = UTF8ToWide(command);
- v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd_wstring.data()),
- cmd_wstring.length());
+ v8::Debug::SendCommand(reinterpret_cast<const uint16_t*>(cmd.data()),
+ cmd.length());
#endif
}
+
// static
-DebuggerAgentImpl* DebuggerAgentManager::GetAgentForCurrentV8Context() {
+DebuggerAgentImpl* DebuggerAgentManager::FindAgentForCurrentV8Context() {
if (!attached_agents_) {
return NULL;
}
DCHECK(!attached_agents_->isEmpty());
- // TODO(yurys): find agent for current v8 global context. Now we return first
- // agent in the set.
- return *attached_agents_->begin();
+
+ WebCore::Frame* frame = WebCore::V8Proxy::retrieveActiveFrame();
+ if (!frame) {
+ return NULL;
+ }
+ WebCore::Page* page = frame->page();
+ for (AttachedAgentsSet::iterator it = attached_agents_->begin();
+ it != attached_agents_->end(); ++it) {
+ if ((*it)->GetPage() == page) {
+ return *it;
+ }
+ }
+ return NULL;
+}
+
+const std::string DebuggerAgentManager::ReplaceRequestSequenceId(
+ const std::string& request,
+ WebDevToolsAgent* webdevtools_agent) {
+ OwnPtr<Value> message(JSONReader::Read(request,
+ false /* allow_trailing_comma */));
+ if (!message.get()) {
+ return request;
+ }
+ if (!message->IsType(Value::TYPE_DICTIONARY)) {
+ return request;
+ }
+ DictionaryValue* m = static_cast<DictionaryValue*>(message.get());
+
+ std::string type;
+ if (!(m->GetString(L"type", &type) && type == "request")) {
+ return request;
+ }
+
+ DictionaryValue new_seq;
+ Value* request_seq;
+ if (m->Get(L"seq", &request_seq)) {
+ new_seq.Set(L"request_seq", request_seq->DeepCopy());
+ }
+
+ // 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));
+
+ // TODO(yurys): fix v8 parser so that it handle objects as ids correctly.
+ std::string new_seq_str;
+ JSONWriter::Write(&new_seq, false /* pretty_print */, &new_seq_str);
+ m->SetString(L"seq", new_seq_str);
+
+ std::string json;
+ JSONWriter::Write(m, false /* pretty_print */, &json);
+ 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) {
+ for (AttachedAgentsSet::iterator it = attached_agents_->begin();
+ it != attached_agents_->end(); ++it) {
+ if ((*it)->webdevtools_agent() == webdevtools_agent) {
+ return *it;
+ }
+ }
+ return NULL;
}
diff --git a/webkit/glue/devtools/debugger_agent_manager.h b/webkit/glue/devtools/debugger_agent_manager.h
index ba48966..39469b8 100644
--- a/webkit/glue/devtools/debugger_agent_manager.h
+++ b/webkit/glue/devtools/debugger_agent_manager.h
@@ -5,12 +5,15 @@
#ifndef WEBKIT_GLUE_DEVTOOLS_DEBUGGER_AGENT_MANAGER_H_
#define WEBKIT_GLUE_DEVTOOLS_DEBUGGER_AGENT_MANAGER_H_
+#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include "base/basictypes.h"
#include "v8/include/v8-debug.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
@@ -34,7 +37,8 @@ class DebuggerAgentManager {
static void DebugBreak(DebuggerAgentImpl* debugger_agent);
static void DebugCommand(const std::string& command);
- static void ExecuteDebuggerCommand(const std::string& command);
+ static void ExecuteDebuggerCommand(const std::string& command,
+ WebDevToolsAgent* webdevtools_agent);
private:
DebuggerAgentManager();
@@ -44,7 +48,16 @@ class DebuggerAgentManager {
int length,
void* data);
static void DebuggerOutput(const std::string& out);
- static DebuggerAgentImpl* GetAgentForCurrentV8Context();
+ static void SendCommandToV8(const std::wstring& cmd);
+ static bool SendCommandResponse(DictionaryValue* response);
+
+ static DebuggerAgentImpl* FindAgentForCurrentV8Context();
+ static DebuggerAgentImpl* FindDebuggerAgentForToolsAgent(
+ WebDevToolsAgent* webdevtools_agent);
+
+ static const std::string ReplaceRequestSequenceId(
+ const std::string& request,
+ WebDevToolsAgent* webdevtools_agent);
typedef HashSet<DebuggerAgentImpl*> AttachedAgentsSet;
static AttachedAgentsSet* attached_agents_;
diff --git a/webkit/glue/webdevtoolsagent.h b/webkit/glue/webdevtoolsagent.h
index e96cfc1..30b7b5d5 100644
--- a/webkit/glue/webdevtoolsagent.h
+++ b/webkit/glue/webdevtoolsagent.h
@@ -24,7 +24,9 @@ class WebDevToolsAgent {
virtual void InspectElement(int x, int y) = 0;
// Asynchronously executes debugger command in the render thread.
- static void ExecuteDebuggerCommand(const std::string& command);
+ // |webdevtools_agent| will be used for sending response.
+ static void ExecuteDebuggerCommand(const std::string& command,
+ WebDevToolsAgent* webdevtools_agent);
private:
DISALLOW_COPY_AND_ASSIGN(WebDevToolsAgent);
diff --git a/webkit/glue/webdevtoolsagent_impl.cc b/webkit/glue/webdevtoolsagent_impl.cc
index 5a4c4b4..e5cf8ad 100644
--- a/webkit/glue/webdevtoolsagent_impl.cc
+++ b/webkit/glue/webdevtoolsagent_impl.cc
@@ -59,7 +59,9 @@ void WebDevToolsAgentImpl::Attach() {
return;
}
debugger_agent_impl_.set(
- new DebuggerAgentImpl(debugger_agent_delegate_stub_.get()));
+ new DebuggerAgentImpl(web_view_impl_,
+ debugger_agent_delegate_stub_.get(),
+ this));
dom_agent_impl_.set(new DomAgentImpl(dom_agent_delegate_stub_.get()));
net_agent_impl_.set(new NetAgentImpl(net_agent_delegate_stub_.get()));
@@ -236,6 +238,8 @@ void WebDevToolsAgentImpl::SendRpcMessage(const std::string& raw_msg) {
}
// static
-void WebDevToolsAgent::ExecuteDebuggerCommand(const std::string& command) {
- DebuggerAgentManager::ExecuteDebuggerCommand(command);
+void WebDevToolsAgent::ExecuteDebuggerCommand(
+ const std::string& command,
+ WebDevToolsAgent* webdevtools_agent) {
+ DebuggerAgentManager::ExecuteDebuggerCommand(command, webdevtools_agent);
}