summaryrefslogtreecommitdiffstats
path: root/chrome/browser/debugger/debugger_remote_service.cc
diff options
context:
space:
mode:
authorapavlov@chromium.org <apavlov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-10 08:42:52 +0000
committerapavlov@chromium.org <apavlov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-10 08:42:52 +0000
commitc0f5a32c2e025e3a2801a254cfeef5987c96199f (patch)
tree5342d84dfd056f4296fa4952f7677fe5039b0398 /chrome/browser/debugger/debugger_remote_service.cc
parent609eeec226e06466acb6ccc0ea5d59d453e6623e (diff)
downloadchromium_src-c0f5a32c2e025e3a2801a254cfeef5987c96199f.zip
chromium_src-c0f5a32c2e025e3a2801a254cfeef5987c96199f.tar.gz
chromium_src-c0f5a32c2e025e3a2801a254cfeef5987c96199f.tar.bz2
Review URL: http://codereview.chromium.org/93119
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15736 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/debugger/debugger_remote_service.cc')
-rw-r--r--chrome/browser/debugger/debugger_remote_service.cc224
1 files changed, 140 insertions, 84 deletions
diff --git a/chrome/browser/debugger/debugger_remote_service.cc b/chrome/browser/debugger/debugger_remote_service.cc
index 95e8ec6..f2a0b68 100644
--- a/chrome/browser/debugger/debugger_remote_service.cc
+++ b/chrome/browser/debugger/debugger_remote_service.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// This file contains implementations of the DebuggerRemoteService methods,
+// defines DebuggerRemoteService and DebuggerRemoteServiceCommand constants.
+
#include "chrome/browser/debugger/debugger_remote_service.h"
#include "base/json_reader.h"
@@ -17,6 +20,20 @@
#include "chrome/common/devtools_messages.h"
#include "chrome/common/render_messages.h"
+namespace {
+
+// A constant for the "data" JSON message field.
+// The type is wstring because the constant is used to get a
+// DictionaryValue field (which requires a wide string).
+static const std::wstring kDataWide = L"data";
+
+// A constant for the "result" JSON message field.
+// The type is wstring because the constant is used to get a
+// DictionaryValue field (which requires a wide string).
+static const std::wstring kResultWide = L"result";
+
+} // namespace
+
const std::string DebuggerRemoteServiceCommand::kAttach = "attach";
const std::string DebuggerRemoteServiceCommand::kDetach = "detach";
const std::string DebuggerRemoteServiceCommand::kDebuggerCommand =
@@ -25,15 +42,17 @@ const std::string DebuggerRemoteServiceCommand::kEvaluateJavascript =
"evaluate_javascript";
const std::string DebuggerRemoteService::kToolName = "V8Debugger";
-const std::wstring DebuggerRemoteService::kDataWide = L"data";
-const std::wstring DebuggerRemoteService::kResultWide = L"result";
DebuggerRemoteService::DebuggerRemoteService(DevToolsProtocolHandler* delegate)
: delegate_(delegate) {}
DebuggerRemoteService::~DebuggerRemoteService() {}
-// message from remote debugger
+// This method handles the V8Debugger tool commands which are
+// retrieved from the request "command" field. If an operation result
+// is ready off-hand (synchronously), it is sent back to the remote debugger.
+// Otherwise the corresponding response is received through IPC from the
+// V8 debugger via DevToolsClientHost.
void DebuggerRemoteService::HandleMessage(
const DevToolsRemoteMessage& message) {
static const std::wstring kCommandWide = L"command";
@@ -63,7 +82,7 @@ void DebuggerRemoteService::HandleMessage(
if (destination.size() == 0) {
// Unknown command (bad format?)
NOTREACHED();
- response.SetInteger(kResultWide, Result::kUnknownCommand);
+ response.SetInteger(kResultWide, RESULT_UNKNOWN_COMMAND);
SendResponse(response, message.tool(), message.destination());
return;
}
@@ -73,66 +92,18 @@ void DebuggerRemoteService::HandleMessage(
if (command == DebuggerRemoteServiceCommand::kAttach) {
// TODO(apavlov): handle 0 for a new tab
response.SetString(kCommandWide, DebuggerRemoteServiceCommand::kAttach);
- AttachTab(destination, &response);
+ AttachToTab(destination, &response);
} else if (command == DebuggerRemoteServiceCommand::kDetach) {
response.SetString(kCommandWide, DebuggerRemoteServiceCommand::kDetach);
- DetachTab(destination, &response);
+ DetachFromTab(destination, &response);
} else if (command == DebuggerRemoteServiceCommand::kDebuggerCommand) {
- if (tab_uid != -1) {
- DevToolsManager* manager = g_browser_process->devtools_manager();
- if (manager == NULL) {
- response.SetInteger(kResultWide, Result::kDebuggerError);
- }
- TabContents* tab_contents = ToTabContents(tab_uid);
- if (tab_contents != NULL) {
- DevToolsClientHost* client_host =
- manager->GetDevToolsClientHostFor(tab_contents->render_view_host());
- if (client_host != NULL) {
- std::string v8_command;
- DictionaryValue* v8_command_value;
- content->GetDictionary(kDataWide, &v8_command_value);
- JSONWriter::Write(v8_command_value, false, &v8_command);
- g_browser_process->devtools_manager()->ForwardToDevToolsAgent(
- client_host, DevToolsAgentMsg_DebuggerCommand(v8_command));
- send_response = false;
- // Do not send response right now as the JSON will be received from
- // the V8 debugger asynchronously
- } else {
- // tab_uid is not being debugged (Attach has not been invoked)
- response.SetInteger(kResultWide, Result::kIllegalTabState);
- }
- } else {
- // Unknown tab_uid from remote debugger
- response.SetInteger(kResultWide, Result::kUnknownTab);
- }
- } else {
- // Invalid tab_uid from remote debugger (perhaps NaN)
- response.SetInteger(kResultWide, Result::kUnknownTab);
- }
+ send_response = DispatchDebuggerCommand(tab_uid, content, &response);
} else if (command == DebuggerRemoteServiceCommand::kEvaluateJavascript) {
- if (tab_uid != -1) {
- TabContents* tab_contents = ToTabContents(tab_uid);
- if (tab_contents != NULL) {
- RenderViewHost* rvh = tab_contents->render_view_host();
- if (rvh != NULL) {
- std::wstring javascript;
- content->GetString(kDataWide, &javascript);
- rvh->Send(new ViewMsg_ScriptEvalRequest(
- rvh->routing_id(), L"", javascript));
- send_response = false;
- } else {
- // No RenderViewHost
- response.SetInteger(kResultWide, Result::kDebuggerError);
- }
- } else {
- // Unknown tab_uid from remote debugger
- response.SetInteger(kResultWide, Result::kUnknownTab);
- }
- }
+ send_response = DispatchEvaluateJavascript(tab_uid, content, &response);
} else {
// Unknown command
NOTREACHED();
- response.SetInteger(kResultWide, Result::kUnknownCommand);
+ response.SetInteger(kResultWide, RESULT_UNKNOWN_COMMAND);
}
if (send_response) {
@@ -144,6 +115,8 @@ void DebuggerRemoteService::OnConnectionLost() {
delegate_->inspectable_tab_proxy()->OnRemoteDebuggerDetached();
}
+// Sends a JSON response to the remote debugger using |response| as content,
+// |tool| and |destination| as the respective header values.
void DebuggerRemoteService::SendResponse(const Value& response,
const std::string& tool,
const std::string& destination) {
@@ -156,6 +129,8 @@ void DebuggerRemoteService::SendResponse(const Value& response,
delegate_->Send(*response_message.get());
}
+// Gets a TabContents instance corresponding to the |tab_uid| using the
+// InspectableTabProxy controllers map, or NULL if none found.
TabContents* DebuggerRemoteService::ToTabContents(int32 tab_uid) {
const InspectableTabProxy::ControllersMap& navcon_map =
delegate_->inspectable_tab_proxy()->controllers_map();
@@ -173,16 +148,17 @@ TabContents* DebuggerRemoteService::ToTabContents(int32 tab_uid) {
}
}
+// Gets invoked from a DevToolsClientHost callback whenever
+// a message from the V8 VM debugger corresponding to |tab_id| is received.
+// Composes a Chrome Developer Tools Protocol JSON response and sends it
+// to the remote debugger.
void DebuggerRemoteService::DebuggerOutput(int32 tab_id,
const std::string& message) {
- std::string content;
- content.append("{\"command\":\"")
- .append(DebuggerRemoteServiceCommand::kDebuggerCommand)
- .append("\",\"result\":")
- .append(IntToString(Result::kOk))
- .append(",\"data\":")
- .append(message)
- .append("}");
+ std::string content = StringPrintf(
+ "{\"command\":\"%s\",\"result\":%s,\"data\":%s}",
+ DebuggerRemoteServiceCommand::kDebuggerCommand.c_str(),
+ IntToString(RESULT_OK).c_str(),
+ message.c_str());
scoped_ptr<DevToolsRemoteMessage> response_message(
DevToolsRemoteMessageBuilder::instance().Create(
kToolName,
@@ -191,63 +167,69 @@ void DebuggerRemoteService::DebuggerOutput(int32 tab_id,
delegate_->Send(*(response_message.get()));
}
-void DebuggerRemoteService::AttachTab(const std::string& destination,
- DictionaryValue* response) {
+// Attaches a remote debugger to the target tab specified by |destination|
+// by posting the DevToolsAgentMsg_Attach message and sends a response
+// to the remote debugger immediately.
+void DebuggerRemoteService::AttachToTab(const std::string& destination,
+ DictionaryValue* response) {
int32 tab_uid = -1;
StringToInt(destination, &tab_uid);
if (tab_uid < 0) {
// Bad tab_uid received from remote debugger (perhaps NaN)
- response->SetInteger(kResultWide, Result::kUnknownTab);
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
return;
}
if (tab_uid == 0) { // single tab_uid
// We've been asked to open a new tab with URL.
// TODO(apavlov): implement
NOTIMPLEMENTED();
- response->SetInteger(kResultWide, Result::kUnknownTab);
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
return;
}
TabContents* tab_contents = ToTabContents(tab_uid);
if (tab_contents == NULL) {
- // No active web contents with tab_uid
- response->SetInteger(kResultWide, Result::kUnknownTab);
+ // No active tab contents with tab_uid
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
return;
}
RenderViewHost* target_host = tab_contents->render_view_host();
if (g_browser_process->devtools_manager()->GetDevToolsClientHostFor(
- target_host) == NULL) {
+ target_host) == NULL) {
DevToolsClientHost* client_host =
delegate_->inspectable_tab_proxy()->NewClientHost(tab_uid, this);
DevToolsManager* manager = g_browser_process->devtools_manager();
if (manager != NULL) {
manager->RegisterDevToolsClientHostFor(target_host, client_host);
manager->ForwardToDevToolsAgent(client_host, DevToolsAgentMsg_Attach());
- response->SetInteger(kResultWide, Result::kOk);
+ response->SetInteger(kResultWide, RESULT_OK);
} else {
- response->SetInteger(kResultWide, Result::kDebuggerError);
+ response->SetInteger(kResultWide, RESULT_DEBUGGER_ERROR);
}
} else {
// DevToolsClientHost for this tab already registered
- response->SetInteger(kResultWide, Result::kIllegalTabState);
+ response->SetInteger(kResultWide, RESULT_ILLEGAL_TAB_STATE);
}
}
-void DebuggerRemoteService::DetachTab(const std::string& destination,
- DictionaryValue* response) {
+// Detaches a remote debugger from the target tab specified by |destination|
+// by posting the DevToolsAgentMsg_Detach message and sends a response
+// to the remote debugger immediately.
+void DebuggerRemoteService::DetachFromTab(const std::string& destination,
+ DictionaryValue* response) {
int32 tab_uid = -1;
- int resultCode = -1;
StringToInt(destination, &tab_uid);
if (tab_uid == -1) {
// Bad tab_uid received from remote debugger (NaN)
if (response != NULL) {
- response->SetInteger(kResultWide, Result::kUnknownTab);
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
}
return;
}
+ int result_code;
TabContents* tab_contents = ToTabContents(tab_uid);
if (tab_contents == NULL) {
// Unknown tab
- resultCode = Result::kUnknownTab;
+ result_code = RESULT_UNKNOWN_TAB;
} else {
DevToolsManager* manager = g_browser_process->devtools_manager();
if (manager != NULL) {
@@ -257,17 +239,91 @@ void DebuggerRemoteService::DetachTab(const std::string& destination,
manager->ForwardToDevToolsAgent(
client_host, DevToolsAgentMsg_Detach());
client_host->InspectedTabClosing();
- resultCode = Result::kOk;
+ result_code = RESULT_OK;
} else {
// No client host registered
- resultCode = Result::kUnknownTab;
+ result_code = RESULT_UNKNOWN_TAB;
}
} else {
// No DevToolsManager
- resultCode = Result::kDebuggerError;
+ result_code = RESULT_DEBUGGER_ERROR;
}
}
if (response != NULL) {
- response->SetInteger(kResultWide, resultCode);
+ response->SetInteger(kResultWide, result_code);
+ }
+}
+
+// Sends a V8 debugger command to the target tab V8 debugger.
+// Does not send back a response (which is received asynchronously
+// through IPC) unless an error occurs before the command has actually
+// been sent.
+bool DebuggerRemoteService::DispatchDebuggerCommand(int tab_uid,
+ DictionaryValue* content,
+ DictionaryValue* response) {
+ if (tab_uid == -1) {
+ // Invalid tab_uid from remote debugger (perhaps NaN)
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
+ return true;
+ }
+ DevToolsManager* manager = g_browser_process->devtools_manager();
+ if (manager == NULL) {
+ response->SetInteger(kResultWide, RESULT_DEBUGGER_ERROR);
+ return true;
+ }
+ TabContents* tab_contents = ToTabContents(tab_uid);
+ if (tab_contents == NULL) {
+ // Unknown tab_uid from remote debugger
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
+ return true;
+ }
+ DevToolsClientHost* client_host =
+ manager->GetDevToolsClientHostFor(tab_contents->render_view_host());
+ if (client_host == NULL) {
+ // tab_uid is not being debugged (Attach has not been invoked)
+ response->SetInteger(kResultWide, RESULT_ILLEGAL_TAB_STATE);
+ return true;
+ }
+ std::string v8_command;
+ DictionaryValue* v8_command_value;
+ content->GetDictionary(kDataWide, &v8_command_value);
+ JSONWriter::Write(v8_command_value, false, &v8_command);
+ g_browser_process->devtools_manager()->ForwardToDevToolsAgent(
+ client_host, DevToolsAgentMsg_DebuggerCommand(v8_command));
+ // Do not send the response right now, as the JSON will be received from
+ // the V8 debugger asynchronously.
+ return false;
+}
+
+// Sends the immediate "evaluate Javascript" command to the V8 debugger.
+// The evaluation result is not sent back to the client as this command
+// is in fact needed to invoke processing of queued debugger commands.
+bool DebuggerRemoteService::DispatchEvaluateJavascript(
+ int tab_uid,
+ DictionaryValue* content,
+ DictionaryValue* response) {
+ if (tab_uid == -1) {
+ // Invalid tab_uid from remote debugger (perhaps NaN)
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
+ return true;
+ }
+ TabContents* tab_contents = ToTabContents(tab_uid);
+ if (tab_contents == NULL) {
+ // Unknown tab_uid from remote debugger
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
+ return true;
+ }
+ RenderViewHost* render_view_host = tab_contents->render_view_host();
+ if (render_view_host == NULL) {
+ // No RenderViewHost
+ response->SetInteger(kResultWide, RESULT_UNKNOWN_TAB);
+ return true;
}
+ std::wstring javascript;
+ content->GetString(kDataWide, &javascript);
+ render_view_host->Send(
+ new ViewMsg_ScriptEvalRequest(render_view_host->routing_id(),
+ L"",
+ javascript));
+ return false;
}