Commit ba67dc1a authored by eustas@chromium.org's avatar eustas@chromium.org

DevTools: allow embedder handling remote debugger commands.

BUG=373325

Review URL: https://codereview.chromium.org/290873002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271605 0039d316-1c4b-4281-b951-d872f2087c98
parent 33b56822
...@@ -26,3 +26,9 @@ void ChromeDevToolsManagerDelegate::Inspect( ...@@ -26,3 +26,9 @@ void ChromeDevToolsManagerDelegate::Inspect(
DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host); DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host);
#endif #endif
} }
base::DictionaryValue* ChromeDevToolsManagerDelegate::HandleCommand(
content::DevToolsAgentHost* agent_host,
base::DictionaryValue* command_dict) {
return NULL;
}
...@@ -17,6 +17,9 @@ class ChromeDevToolsManagerDelegate : public content::DevToolsManagerDelegate { ...@@ -17,6 +17,9 @@ class ChromeDevToolsManagerDelegate : public content::DevToolsManagerDelegate {
// content::DevToolsManagerDelegate overrides: // content::DevToolsManagerDelegate overrides:
virtual void Inspect(content::BrowserContext* browser_context, virtual void Inspect(content::BrowserContext* browser_context,
content::DevToolsAgentHost* agent_host) OVERRIDE; content::DevToolsAgentHost* agent_host) OVERRIDE;
virtual base::DictionaryValue* HandleCommand(
content::DevToolsAgentHost* agent_host,
base::DictionaryValue* command_dict) OVERRIDE;
private: private:
DISALLOW_COPY_AND_ASSIGN(ChromeDevToolsManagerDelegate); DISALLOW_COPY_AND_ASSIGN(ChromeDevToolsManagerDelegate);
......
...@@ -6,13 +6,23 @@ ...@@ -6,13 +6,23 @@
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/strings/stringprintf.h"
namespace { namespace {
const char kErrorCodeParam[] = "code";
const char kErrorParam[] = "error";
const char kErrorMessageParam[] = "message";
const char kIdParam[] = "id"; const char kIdParam[] = "id";
const char kMethodParam[] = "method"; const char kMethodParam[] = "method";
const char kParamsParam[] = "params"; const char kParamsParam[] = "params";
const char kErrorParam[] = "error"; const char kResultParam[] = "result";
const char kErrorCodeParam[] = "code";
// JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object
enum Error {
kErrorInvalidParams = -32602
};
} // namespace } // namespace
DevToolsProtocol::Message::~Message() { DevToolsProtocol::Message::~Message() {
...@@ -46,6 +56,20 @@ std::string DevToolsProtocol::Command::Serialize() { ...@@ -46,6 +56,20 @@ std::string DevToolsProtocol::Command::Serialize() {
return json_command; 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() { DevToolsProtocol::Notification::~Notification() {
} }
...@@ -57,9 +81,55 @@ DevToolsProtocol::Notification::Notification(const std::string& method, ...@@ -57,9 +81,55 @@ DevToolsProtocol::Notification::Notification(const std::string& method,
DevToolsProtocol::Response::~Response() { 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), : 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, &params);
return new Command(id, method, params ? params->DeepCopy() : NULL);
} }
// static // static
...@@ -98,5 +168,5 @@ DevToolsProtocol::Response* DevToolsProtocol::ParseResponse( ...@@ -98,5 +168,5 @@ DevToolsProtocol::Response* DevToolsProtocol::ParseResponse(
base::DictionaryValue* error_dict = NULL; base::DictionaryValue* error_dict = NULL;
if (dict->GetDictionary(kErrorParam, &error_dict)) if (dict->GetDictionary(kErrorParam, &error_dict))
error_dict->GetInteger(kErrorCodeParam, &error_code); error_dict->GetInteger(kErrorCodeParam, &error_code);
return new Response(id, error_code); return new Response(id, error_code, std::string());
} }
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
// from chrome component (see content/browser/devtools/devtools_protocol.*). // from chrome component (see content/browser/devtools/devtools_protocol.*).
class DevToolsProtocol { class DevToolsProtocol {
public: public:
class Response;
class Message { class Message {
public: public:
virtual ~Message(); virtual ~Message();
...@@ -43,6 +45,12 @@ class DevToolsProtocol { ...@@ -43,6 +45,12 @@ class DevToolsProtocol {
int id() { return id_; } int id() { return id_; }
std::string Serialize(); 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: private:
int id_; int id_;
...@@ -56,12 +64,18 @@ class DevToolsProtocol { ...@@ -56,12 +64,18 @@ class DevToolsProtocol {
int id() { return id_; } int id() { return id_; }
int error_code() { return error_code_; } int error_code() { return error_code_; }
// Result ownership is passed to the caller.
base::DictionaryValue* Serialize();
private: private:
friend class DevToolsProtocol; 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 id_;
int error_code_; int error_code_;
std::string error_message_;
scoped_ptr<base::DictionaryValue> result_;
DISALLOW_COPY_AND_ASSIGN(Response); DISALLOW_COPY_AND_ASSIGN(Response);
}; };
...@@ -80,6 +94,9 @@ class DevToolsProtocol { ...@@ -80,6 +94,9 @@ class DevToolsProtocol {
DISALLOW_COPY_AND_ASSIGN(Notification); DISALLOW_COPY_AND_ASSIGN(Notification);
}; };
// Result ownership is passed to the caller.
static Command* ParseCommand(base::DictionaryValue* command_dict);
// Result ownership is passed to the caller. // Result ownership is passed to the caller.
static Notification* ParseNotification(const std::string& json); static Notification* ParseNotification(const std::string& json);
......
...@@ -51,6 +51,8 @@ class CONTENT_EXPORT DevToolsManagerImpl ...@@ -51,6 +51,8 @@ class CONTENT_EXPORT DevToolsManagerImpl
void DispatchOnInspectorFrontend(DevToolsAgentHost* agent_host, void DispatchOnInspectorFrontend(DevToolsAgentHost* agent_host,
const std::string& message); const std::string& message);
DevToolsManagerDelegate* delegate() const { return delegate_.get(); }
// DevToolsManager implementation // DevToolsManager implementation
virtual bool DispatchOnInspectorBackend(DevToolsClientHost* from, virtual bool DispatchOnInspectorBackend(DevToolsClientHost* from,
const std::string& message) OVERRIDE; const std::string& message) OVERRIDE;
......
...@@ -216,13 +216,20 @@ scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand( ...@@ -216,13 +216,20 @@ scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand(
std::string* error_response) { std::string* error_response) {
scoped_ptr<base::DictionaryValue> command_dict( scoped_ptr<base::DictionaryValue> command_dict(
ParseMessage(json, error_response)); 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) if (!command_dict)
return NULL; return NULL;
int id; int id;
std::string method; std::string method;
bool ok = command_dict->GetInteger(kIdParam, &id) && id >= 0; bool ok = command_dict->GetInteger(kIdParam, &id) && id >= 0;
ok = ok && ParseMethod(command_dict.get(), &method); ok = ok && ParseMethod(command_dict, &method);
if (!ok) { if (!ok) {
scoped_refptr<Response> response = scoped_refptr<Response> response =
new Response(kNoId, kErrorInvalidRequest, "No such method"); new Response(kNoId, kErrorInvalidRequest, "No such method");
...@@ -244,6 +251,29 @@ DevToolsProtocol::CreateCommand( ...@@ -244,6 +251,29 @@ DevToolsProtocol::CreateCommand(
return new Command(id, method, params); 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 // static
scoped_refptr<DevToolsProtocol::Notification> scoped_refptr<DevToolsProtocol::Notification>
DevToolsProtocol::ParseNotification(const std::string& json) { DevToolsProtocol::ParseNotification(const std::string& json) {
......
...@@ -157,25 +157,32 @@ class DevToolsProtocol { ...@@ -157,25 +157,32 @@ class DevToolsProtocol {
DISALLOW_COPY_AND_ASSIGN(Handler); 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( CONTENT_EXPORT static scoped_refptr<Command> ParseCommand(
const std::string& json, const std::string& json,
std::string* error_response); 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( CONTENT_EXPORT static scoped_refptr<Command> CreateCommand(
int id, int id,
const std::string& method, const std::string& method,
base::DictionaryValue* params); base::DictionaryValue* params);
CONTENT_EXPORT static scoped_refptr<Response> ParseResponse(
base::DictionaryValue* response_dict);
static scoped_refptr<Notification> ParseNotification( static scoped_refptr<Notification> ParseNotification(
const std::string& json); const std::string& json);
static scoped_refptr<Notification> CreateNotification( static scoped_refptr<Notification> CreateNotification(
const std::string& method, base::DictionaryValue* params); const std::string& method, base::DictionaryValue* params);
private:
static base::DictionaryValue* ParseMessage(const std::string& json,
std::string* error_response);
DevToolsProtocol() {} DevToolsProtocol() {}
~DevToolsProtocol() {} ~DevToolsProtocol() {}
}; };
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "content/common/devtools_messages.h" #include "content/common/devtools_messages.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/public/browser/content_browser_client.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_service.h"
#include "content/public/browser/notification_types.h" #include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_iterator.h" #include "content/public/browser/render_widget_host_iterator.h"
...@@ -184,12 +185,26 @@ RenderViewHost* RenderViewDevToolsAgentHost::GetRenderViewHost() { ...@@ -184,12 +185,26 @@ RenderViewHost* RenderViewDevToolsAgentHost::GetRenderViewHost() {
void RenderViewDevToolsAgentHost::DispatchOnInspectorBackend( void RenderViewDevToolsAgentHost::DispatchOnInspectorBackend(
const std::string& message) { const std::string& message) {
std::string error_message; std::string error_message;
scoped_ptr<base::DictionaryValue> message_dict(
DevToolsProtocol::ParseMessage(message, &error_message));
scoped_refptr<DevToolsProtocol::Command> command = scoped_refptr<DevToolsProtocol::Command> command =
DevToolsProtocol::ParseCommand(message, &error_message); DevToolsProtocol::ParseCommand(message_dict.get(), &error_message);
if (command) { if (command) {
scoped_refptr<DevToolsProtocol::Response> overridden_response = scoped_refptr<DevToolsProtocol::Response> overridden_response;
overrides_handler_->HandleCommand(command);
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) if (!overridden_response)
overridden_response = tracing_handler_->HandleCommand(command); overridden_response = tracing_handler_->HandleCommand(command);
if (!overridden_response) if (!overridden_response)
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
#ifndef CONTENT_PUBLIC_BROWSER_DEVTOOLS_MANAGER_DELEGATE_H_ #ifndef CONTENT_PUBLIC_BROWSER_DEVTOOLS_MANAGER_DELEGATE_H_
#define CONTENT_PUBLIC_BROWSER_DEVTOOLS_MANAGER_DELEGATE_H_ #define CONTENT_PUBLIC_BROWSER_DEVTOOLS_MANAGER_DELEGATE_H_
namespace base {
class DictionaryValue;
}
namespace content { namespace content {
class BrowserContext; class BrowserContext;
...@@ -17,6 +21,11 @@ class DevToolsManagerDelegate { ...@@ -17,6 +21,11 @@ class DevToolsManagerDelegate {
// Opens the inspector for |agent_host|. // Opens the inspector for |agent_host|.
virtual void Inspect(BrowserContext* browser_context, virtual void Inspect(BrowserContext* browser_context,
DevToolsAgentHost* agent_host) = 0; DevToolsAgentHost* agent_host) = 0;
// Result ownership is passed to the caller.
virtual base::DictionaryValue* HandleCommand(
DevToolsAgentHost* agent_host,
base::DictionaryValue* command) = 0;
}; };
} // namespace content } // namespace content
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment