diff options
author | apavlov@chromium.org <apavlov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-10 08:42:52 +0000 |
---|---|---|
committer | apavlov@chromium.org <apavlov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-10 08:42:52 +0000 |
commit | c0f5a32c2e025e3a2801a254cfeef5987c96199f (patch) | |
tree | 5342d84dfd056f4296fa4952f7677fe5039b0398 /chrome/browser/debugger/debugger_remote_service.cc | |
parent | 609eeec226e06466acb6ccc0ea5d59d453e6623e (diff) | |
download | chromium_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.cc | 224 |
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; } |