diff options
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/devtools/debugger_agent_impl.cc | 14 | ||||
-rw-r--r-- | webkit/glue/devtools/debugger_agent_impl.h | 13 | ||||
-rw-r--r-- | webkit/glue/devtools/debugger_agent_manager.cc | 165 | ||||
-rw-r--r-- | webkit/glue/devtools/debugger_agent_manager.h | 17 | ||||
-rw-r--r-- | webkit/glue/webdevtoolsagent.h | 4 | ||||
-rw-r--r-- | webkit/glue/webdevtoolsagent_impl.cc | 10 |
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); } |