diff options
9 files changed, 173 insertions, 14 deletions
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc index b2cd1ee..9b1f08b 100644 --- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc +++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc @@ -26,3 +26,9 @@ void ChromeDevToolsManagerDelegate::Inspect( DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host); #endif } + +base::DictionaryValue* ChromeDevToolsManagerDelegate::HandleCommand( + content::DevToolsAgentHost* agent_host, + base::DictionaryValue* command_dict) { + return NULL; +} diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.h b/chrome/browser/devtools/chrome_devtools_manager_delegate.h index f1bed42..4de8369 100644 --- a/chrome/browser/devtools/chrome_devtools_manager_delegate.h +++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.h @@ -17,6 +17,9 @@ class ChromeDevToolsManagerDelegate : public content::DevToolsManagerDelegate { // content::DevToolsManagerDelegate overrides: virtual void Inspect(content::BrowserContext* browser_context, content::DevToolsAgentHost* agent_host) OVERRIDE; + virtual base::DictionaryValue* HandleCommand( + content::DevToolsAgentHost* agent_host, + base::DictionaryValue* command_dict) OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(ChromeDevToolsManagerDelegate); diff --git a/chrome/browser/devtools/devtools_protocol.cc b/chrome/browser/devtools/devtools_protocol.cc index f14864c..ef7cb6a 100644 --- a/chrome/browser/devtools/devtools_protocol.cc +++ b/chrome/browser/devtools/devtools_protocol.cc @@ -6,13 +6,23 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" +#include "base/strings/stringprintf.h" namespace { + +const char kErrorCodeParam[] = "code"; +const char kErrorParam[] = "error"; +const char kErrorMessageParam[] = "message"; const char kIdParam[] = "id"; const char kMethodParam[] = "method"; const char kParamsParam[] = "params"; -const char kErrorParam[] = "error"; -const char kErrorCodeParam[] = "code"; +const char kResultParam[] = "result"; + +// JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object +enum Error { + kErrorInvalidParams = -32602 +}; + } // namespace DevToolsProtocol::Message::~Message() { @@ -46,6 +56,20 @@ std::string DevToolsProtocol::Command::Serialize() { return json_command; } +scoped_ptr<DevToolsProtocol::Response> +DevToolsProtocol::Command::SuccessResponse(base::DictionaryValue* result) { + return scoped_ptr<DevToolsProtocol::Response>( + new DevToolsProtocol::Response(id_, result)); +} + +scoped_ptr<DevToolsProtocol::Response> +DevToolsProtocol::Command::InvalidParamResponse(const std::string& param) { + std::string message = + base::StringPrintf("Missing or invalid '%s' parameter", param.c_str()); + return scoped_ptr<DevToolsProtocol::Response>( + new DevToolsProtocol::Response(id_, kErrorInvalidParams, message)); +} + DevToolsProtocol::Notification::~Notification() { } @@ -57,9 +81,55 @@ DevToolsProtocol::Notification::Notification(const std::string& method, DevToolsProtocol::Response::~Response() { } -DevToolsProtocol::Response::Response(int id, int error_code) +DevToolsProtocol::Response::Response(int id, + int error_code, + const std::string error_message) + : id_(id), + error_code_(error_code), + error_message_(error_message) { +} + +DevToolsProtocol::Response::Response(int id, base::DictionaryValue* result) : id_(id), - error_code_(error_code) { + error_code_(0), + result_(result) { +} + +base::DictionaryValue* DevToolsProtocol::Response::Serialize() { + base::DictionaryValue* response = new base::DictionaryValue(); + + response->SetInteger(kIdParam, id_); + + if (error_code_) { + base::DictionaryValue* error_object = new base::DictionaryValue(); + response->Set(kErrorParam, error_object); + error_object->SetInteger(kErrorCodeParam, error_code_); + if (!error_message_.empty()) + error_object->SetString(kErrorMessageParam, error_message_); + } else if (result_) { + response->Set(kResultParam, result_->DeepCopy()); + } + + return response; +} + +// static +DevToolsProtocol::Command* DevToolsProtocol::ParseCommand( + base::DictionaryValue* command_dict) { + if (!command_dict) + return NULL; + + int id; + if (!command_dict->GetInteger(kIdParam, &id) || id < 0) + return NULL; + + std::string method; + if (!command_dict->GetString(kMethodParam, &method)) + return NULL; + + base::DictionaryValue* params = NULL; + command_dict->GetDictionary(kParamsParam, ¶ms); + return new Command(id, method, params ? params->DeepCopy() : NULL); } // static @@ -98,5 +168,5 @@ DevToolsProtocol::Response* DevToolsProtocol::ParseResponse( base::DictionaryValue* error_dict = NULL; if (dict->GetDictionary(kErrorParam, &error_dict)) error_dict->GetInteger(kErrorCodeParam, &error_code); - return new Response(id, error_code); + return new Response(id, error_code, std::string()); } diff --git a/chrome/browser/devtools/devtools_protocol.h b/chrome/browser/devtools/devtools_protocol.h index 9b15b9e..2e65810 100644 --- a/chrome/browser/devtools/devtools_protocol.h +++ b/chrome/browser/devtools/devtools_protocol.h @@ -16,6 +16,8 @@ // from chrome component (see content/browser/devtools/devtools_protocol.*). class DevToolsProtocol { public: + class Response; + class Message { public: virtual ~Message(); @@ -43,6 +45,12 @@ class DevToolsProtocol { int id() { return id_; } std::string Serialize(); + // Creates success response. Takes ownership of |result|. + scoped_ptr<Response> SuccessResponse(base::DictionaryValue* result); + + // Creates error response. + scoped_ptr<Response> InvalidParamResponse(const std::string& param); + private: int id_; @@ -56,12 +64,18 @@ class DevToolsProtocol { int id() { return id_; } int error_code() { return error_code_; } + // Result ownership is passed to the caller. + base::DictionaryValue* Serialize(); + private: friend class DevToolsProtocol; - Response(int id, int error_code); + Response(int id, int error_code, const std::string error_message); + Response(int id, base::DictionaryValue* result); int id_; int error_code_; + std::string error_message_; + scoped_ptr<base::DictionaryValue> result_; DISALLOW_COPY_AND_ASSIGN(Response); }; @@ -81,6 +95,9 @@ class DevToolsProtocol { }; // Result ownership is passed to the caller. + static Command* ParseCommand(base::DictionaryValue* command_dict); + + // Result ownership is passed to the caller. static Notification* ParseNotification(const std::string& json); // Result ownership is passed to the caller. diff --git a/content/browser/devtools/devtools_manager_impl.h b/content/browser/devtools/devtools_manager_impl.h index 8067662..19b6918 100644 --- a/content/browser/devtools/devtools_manager_impl.h +++ b/content/browser/devtools/devtools_manager_impl.h @@ -51,6 +51,8 @@ class CONTENT_EXPORT DevToolsManagerImpl void DispatchOnInspectorFrontend(DevToolsAgentHost* agent_host, const std::string& message); + DevToolsManagerDelegate* delegate() const { return delegate_.get(); } + // DevToolsManager implementation virtual bool DispatchOnInspectorBackend(DevToolsClientHost* from, const std::string& message) OVERRIDE; diff --git a/content/browser/devtools/devtools_protocol.cc b/content/browser/devtools/devtools_protocol.cc index f3c393d..e6800e7 100644 --- a/content/browser/devtools/devtools_protocol.cc +++ b/content/browser/devtools/devtools_protocol.cc @@ -216,13 +216,20 @@ scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand( std::string* error_response) { scoped_ptr<base::DictionaryValue> command_dict( ParseMessage(json, error_response)); + return ParseCommand(command_dict.get(), error_response); +} + +// static +scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand( + base::DictionaryValue* command_dict, + std::string* error_response) { if (!command_dict) return NULL; int id; std::string method; bool ok = command_dict->GetInteger(kIdParam, &id) && id >= 0; - ok = ok && ParseMethod(command_dict.get(), &method); + ok = ok && ParseMethod(command_dict, &method); if (!ok) { scoped_refptr<Response> response = new Response(kNoId, kErrorInvalidRequest, "No such method"); @@ -244,6 +251,29 @@ DevToolsProtocol::CreateCommand( return new Command(id, method, params); } +//static +scoped_refptr<DevToolsProtocol::Response> +DevToolsProtocol::ParseResponse( + base::DictionaryValue* response_dict) { + int id; + if (!response_dict->GetInteger(kIdParam, &id)) + id = kNoId; + + int error_code; + if (!response_dict->GetInteger(kErrorCodeParam, &error_code)) + return new Response(id, kErrorInternalError, "Invalid response"); + + if (error_code) { + std::string error_message; + response_dict->GetString(kErrorMessageParam, &error_message); + return new Response(id, error_code, error_message); + } + + const base::DictionaryValue* result = NULL; + response_dict->GetDictionary(kResultParam, &result); + return new Response(id, result ? result->DeepCopy() : NULL); +} + // static scoped_refptr<DevToolsProtocol::Notification> DevToolsProtocol::ParseNotification(const std::string& json) { diff --git a/content/browser/devtools/devtools_protocol.h b/content/browser/devtools/devtools_protocol.h index 15b0a80..65a4925 100644 --- a/content/browser/devtools/devtools_protocol.h +++ b/content/browser/devtools/devtools_protocol.h @@ -157,25 +157,32 @@ class DevToolsProtocol { DISALLOW_COPY_AND_ASSIGN(Handler); }; + CONTENT_EXPORT static base::DictionaryValue* ParseMessage( + const std::string& json, + std::string* error_response); + CONTENT_EXPORT static scoped_refptr<Command> ParseCommand( const std::string& json, std::string* error_response); + CONTENT_EXPORT static scoped_refptr<Command> ParseCommand( + base::DictionaryValue* command_dict, + std::string* error_response); + CONTENT_EXPORT static scoped_refptr<Command> CreateCommand( int id, const std::string& method, base::DictionaryValue* params); + CONTENT_EXPORT static scoped_refptr<Response> ParseResponse( + base::DictionaryValue* response_dict); + static scoped_refptr<Notification> ParseNotification( const std::string& json); static scoped_refptr<Notification> CreateNotification( const std::string& method, base::DictionaryValue* params); - private: - static base::DictionaryValue* ParseMessage(const std::string& json, - std::string* error_response); - DevToolsProtocol() {} ~DevToolsProtocol() {} }; diff --git a/content/browser/devtools/render_view_devtools_agent_host.cc b/content/browser/devtools/render_view_devtools_agent_host.cc index 8867e54..7d948d6 100644 --- a/content/browser/devtools/render_view_devtools_agent_host.cc +++ b/content/browser/devtools/render_view_devtools_agent_host.cc @@ -20,6 +20,7 @@ #include "content/common/devtools_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/devtools_manager_delegate.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_widget_host_iterator.h" @@ -184,12 +185,26 @@ RenderViewHost* RenderViewDevToolsAgentHost::GetRenderViewHost() { void RenderViewDevToolsAgentHost::DispatchOnInspectorBackend( const std::string& message) { std::string error_message; + + scoped_ptr<base::DictionaryValue> message_dict( + DevToolsProtocol::ParseMessage(message, &error_message)); scoped_refptr<DevToolsProtocol::Command> command = - DevToolsProtocol::ParseCommand(message, &error_message); + DevToolsProtocol::ParseCommand(message_dict.get(), &error_message); if (command) { - scoped_refptr<DevToolsProtocol::Response> overridden_response = - overrides_handler_->HandleCommand(command); + scoped_refptr<DevToolsProtocol::Response> overridden_response; + + DevToolsManagerDelegate* delegate = + DevToolsManagerImpl::GetInstance()->delegate(); + if (delegate) { + scoped_ptr<base::DictionaryValue> overridden_response_value( + delegate->HandleCommand(this, message_dict.get())); + if (overridden_response_value) + overridden_response = DevToolsProtocol::ParseResponse( + overridden_response_value.get()); + } + if (!overridden_response) + overridden_response = overrides_handler_->HandleCommand(command); if (!overridden_response) overridden_response = tracing_handler_->HandleCommand(command); if (!overridden_response) diff --git a/content/public/browser/devtools_manager_delegate.h b/content/public/browser/devtools_manager_delegate.h index 92b656d..57579b1 100644 --- a/content/public/browser/devtools_manager_delegate.h +++ b/content/public/browser/devtools_manager_delegate.h @@ -5,6 +5,10 @@ #ifndef CONTENT_PUBLIC_BROWSER_DEVTOOLS_MANAGER_DELEGATE_H_ #define CONTENT_PUBLIC_BROWSER_DEVTOOLS_MANAGER_DELEGATE_H_ +namespace base { +class DictionaryValue; +} + namespace content { class BrowserContext; @@ -17,6 +21,11 @@ class DevToolsManagerDelegate { // Opens the inspector for |agent_host|. virtual void Inspect(BrowserContext* browser_context, DevToolsAgentHost* agent_host) = 0; + + // Result ownership is passed to the caller. + virtual base::DictionaryValue* HandleCommand( + DevToolsAgentHost* agent_host, + base::DictionaryValue* command) = 0; }; } // namespace content |