diff options
author | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-20 11:38:03 +0000 |
---|---|---|
committer | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-20 11:38:03 +0000 |
commit | 0639cfd4ed40aa9450c5781c86d6b47af8396220 (patch) | |
tree | 486f82e04cd53623ffb67ae7932523bde70b118f /content/browser/debugger | |
parent | d641b6e4c2ebf556cb42818e7b3470329baf170c (diff) | |
download | chromium_src-0639cfd4ed40aa9450c5781c86d6b47af8396220.zip chromium_src-0639cfd4ed40aa9450c5781c86d6b47af8396220.tar.gz chromium_src-0639cfd4ed40aa9450c5781c86d6b47af8396220.tar.bz2 |
DevTools: bulk move of legacy protocol back to chrome/.
Review URL: http://codereview.chromium.org/7458015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93182 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/debugger')
25 files changed, 10 insertions, 3219 deletions
diff --git a/content/browser/debugger/DEPS b/content/browser/debugger/DEPS index f7fc3b2..90d5678 100644 --- a/content/browser/debugger/DEPS +++ b/content/browser/debugger/DEPS @@ -8,30 +8,13 @@ include_rules = [ # http://crbug.com/84078 "+chrome/browser/browser_process.h", "+chrome/browser/debugger/devtools_window.h", - "+chrome/browser/download/download_prefs.h", - "+chrome/browser/extensions/extension_host.h", - "+chrome/browser/extensions/extension_message_service.h", - "+chrome/browser/extensions/extension_service.h", "+chrome/browser/io_thread.h", "+chrome/browser/net/chrome_net_log.h", - "+chrome/browser/prefs/pref_service.h", - "+chrome/browser/prefs/scoped_user_pref_update.h", "+chrome/browser/profiles/profile_manager.h", "+chrome/browser/sessions/restore_tab_helper.h", - "+chrome/browser/sessions/session_id.h", - "+chrome/browser/tabs/tab_strip_model.h", - "+chrome/browser/themes/theme_service.h", - "+chrome/browser/themes/theme_service_factory.h", - "+chrome/browser/ui/browser_list.h", - "+chrome/browser/ui/browser_window.h", - "+chrome/browser/ui/shell_dialogs.h", "+chrome/browser/ui/tab_contents/tab_contents_wrapper.h", "+chrome/browser/ui/webui/devtools_ui.h", - "+chrome/common/chrome_paths.h", - "+chrome/common/extensions/extension_messages.h", - "+chrome/common/pref_names.h", "+chrome/common/render_messages.h", - "+chrome/common/url_constants.h", "+ui/base/resource/resource_bundle.h", # DO NOT ADD ANY MORE TO THIS LIST!!! SEE ABOVE COMMENT diff --git a/content/browser/debugger/browser_list_tabcontents_provider.cc b/content/browser/debugger/browser_list_tabcontents_provider.cc deleted file mode 100644 index 3214ded..0000000 --- a/content/browser/debugger/browser_list_tabcontents_provider.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/debugger/browser_list_tabcontents_provider.h" - -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/ui/browser_list.h" - -DevToolsHttpProtocolHandler::InspectableTabs -BrowserListTabContentsProvider::GetInspectableTabs() { - DevToolsHttpProtocolHandler::InspectableTabs tabs; - for (BrowserList::const_iterator it = BrowserList::begin(), - end = BrowserList::end(); it != end; ++it) { - TabStripModel* model = (*it)->tabstrip_model(); - for (int i = 0, size = model->count(); i < size; ++i) - tabs.push_back(model->GetTabContentsAt(i)); - } - return tabs; -} diff --git a/content/browser/debugger/browser_list_tabcontents_provider.h b/content/browser/debugger/browser_list_tabcontents_provider.h deleted file mode 100644 index 9649bb3..0000000 --- a/content/browser/debugger/browser_list_tabcontents_provider.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_DEBUGGER_BROWSER_LIST_TABCONTENTS_PROVIDER_H_ -#define CONTENT_BROWSER_DEBUGGER_BROWSER_LIST_TABCONTENTS_PROVIDER_H_ - -#include "content/browser/debugger/devtools_http_protocol_handler.h" - -class BrowserListTabContentsProvider : - public DevToolsHttpProtocolHandler::TabContentsProvider { - public: - BrowserListTabContentsProvider() {} - virtual ~BrowserListTabContentsProvider() {} - - virtual DevToolsHttpProtocolHandler::InspectableTabs GetInspectableTabs(); - private: - DISALLOW_COPY_AND_ASSIGN(BrowserListTabContentsProvider); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_BROWSER_LIST_TABCONTENTS_PROVIDER_H_ diff --git a/content/browser/debugger/debugger_host.h b/content/browser/debugger/debugger_host.h deleted file mode 100644 index 44482d5..0000000 --- a/content/browser/debugger/debugger_host.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// A part of browser-side server debugger exposed to DebuggerWrapper. - -#ifndef CONTENT_BROWSER_DEBUGGER_DEBUGGER_HOST_H_ -#define CONTENT_BROWSER_DEBUGGER_DEBUGGER_HOST_H_ -#pragma once - -#include <string> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" - -namespace base { -class ListValue; -} - -class DebuggerHost : public base::RefCountedThreadSafe<DebuggerHost> { - public: - DebuggerHost() {} - virtual ~DebuggerHost() {} - - // call before other methods - virtual void Start() = 0; - - // A message from the V8 debugger in the renderer being debugged via - // RenderViewHost - virtual void DebugMessage(const std::wstring& msg) = 0; - // We've been successfully attached to a renderer. - virtual void OnDebugAttach() = 0; - // The renderer we're attached to is gone. - virtual void OnDebugDisconnect() = 0; - - virtual void DidDisconnect() = 0; - virtual void DidConnect() {} - virtual void ProcessCommand(const std::wstring& data) {} - - // Handles messages from debugger UI. - virtual void OnDebuggerHostMsg(const base::ListValue* args) {} - - // Shows the debugger UI and returns true if it has any. - virtual bool ShowWindow() { return false; } - - private: - - DISALLOW_COPY_AND_ASSIGN(DebuggerHost); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEBUGGER_HOST_H_ diff --git a/content/browser/debugger/debugger_remote_service.cc b/content/browser/debugger/debugger_remote_service.cc deleted file mode 100644 index d42decc..0000000 --- a/content/browser/debugger/debugger_remote_service.cc +++ /dev/null @@ -1,337 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// 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 "content/browser/debugger/debugger_remote_service.h" - -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/stringprintf.h" -#include "base/string_number_conversions.h" -#include "base/utf_string_conversions.h" -#include "base/values.h" -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/common/render_messages.h" -#include "content/browser/debugger/devtools_manager.h" -#include "content/browser/debugger/devtools_protocol_handler.h" -#include "content/browser/debugger/devtools_remote_message.h" -#include "content/browser/debugger/inspectable_tab_proxy.h" -#include "content/browser/renderer_host/render_view_host.h" -#include "content/browser/tab_contents/tab_contents.h" -#include "content/common/devtools_messages.h" - -namespace { - -// Constants for the "data", "result", and "command" JSON message fields. -const char kDataKey[] = "data"; -const char kResultKey[] = "result"; -const char kCommandKey[] = "command"; - -} // namespace - -const std::string DebuggerRemoteServiceCommand::kAttach = "attach"; -const std::string DebuggerRemoteServiceCommand::kDetach = "detach"; -const std::string DebuggerRemoteServiceCommand::kDebuggerCommand = - "debugger_command"; -const std::string DebuggerRemoteServiceCommand::kEvaluateJavascript = - "evaluate_javascript"; -const std::string DebuggerRemoteServiceCommand::kFrameNavigate = - "navigated"; -const std::string DebuggerRemoteServiceCommand::kTabClosed = - "closed"; - -const std::string DebuggerRemoteService::kToolName = "V8Debugger"; - -DebuggerRemoteService::DebuggerRemoteService(DevToolsProtocolHandler* delegate) - : delegate_(delegate) {} - -DebuggerRemoteService::~DebuggerRemoteService() {} - -// 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) { - const std::string destination = message.destination(); - scoped_ptr<Value> request(base::JSONReader::Read(message.content(), true)); - if (request.get() == NULL) { - // Bad JSON - NOTREACHED(); - return; - } - DictionaryValue* content; - if (!request->IsType(Value::TYPE_DICTIONARY)) { - NOTREACHED(); // Broken protocol :( - return; - } - content = static_cast<DictionaryValue*>(request.get()); - if (!content->HasKey(kCommandKey)) { - NOTREACHED(); // Broken protocol :( - return; - } - std::string command; - DictionaryValue response; - - content->GetString(kCommandKey, &command); - response.SetString(kCommandKey, command); - bool send_response = true; - if (destination.empty()) { - // Unknown command (bad format?) - NOTREACHED(); - response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); - SendResponse(response, message.tool(), message.destination()); - return; - } - int32 tab_uid = -1; - base::StringToInt(destination, &tab_uid); - - if (command == DebuggerRemoteServiceCommand::kAttach) { - // TODO(apavlov): handle 0 for a new tab - response.SetString(kCommandKey, DebuggerRemoteServiceCommand::kAttach); - AttachToTab(destination, &response); - } else if (command == DebuggerRemoteServiceCommand::kDetach) { - response.SetString(kCommandKey, DebuggerRemoteServiceCommand::kDetach); - DetachFromTab(destination, &response); - } else if (command == DebuggerRemoteServiceCommand::kDebuggerCommand) { - send_response = DispatchDebuggerCommand(tab_uid, content, &response); - } else if (command == DebuggerRemoteServiceCommand::kEvaluateJavascript) { - send_response = DispatchEvaluateJavascript(tab_uid, content, &response); - } else { - // Unknown command - NOTREACHED(); - response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); - } - - if (send_response) { - SendResponse(response, message.tool(), message.destination()); - } -} - -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) { - std::string response_content; - base::JSONWriter::Write(&response, false, &response_content); - scoped_ptr<DevToolsRemoteMessage> response_message( - DevToolsRemoteMessageBuilder::instance().Create(tool, - destination, - response_content)); - 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::TabMap& tab_map = - delegate_->inspectable_tab_proxy()->tab_map(); - InspectableTabProxy::TabMap::const_iterator it = tab_map.find(tab_uid); - if (it != tab_map.end()) { - TabContents* tab_contents = it->second->tab_contents(); - if (tab_contents == NULL) { - return NULL; - } else { - return tab_contents; - } - } else { - return NULL; - } -} - -// 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_uid, - const std::string& message) { - std::string content = StringPrintf( - "{\"command\":\"%s\",\"result\":%s,\"data\":%s}", - DebuggerRemoteServiceCommand::kDebuggerCommand.c_str(), - base::IntToString(RESULT_OK).c_str(), - message.c_str()); - scoped_ptr<DevToolsRemoteMessage> response_message( - DevToolsRemoteMessageBuilder::instance().Create( - kToolName, - base::IntToString(tab_uid), - content)); - delegate_->Send(*(response_message.get())); -} - -// Gets invoked from a DevToolsClientHost callback whenever -// a tab corresponding to |tab_id| changes its URL. |url| is the new -// URL of the tab (may be the same as the previous one if the tab is reloaded). -// Sends the corresponding message to the remote debugger. -void DebuggerRemoteService::FrameNavigate(int32 tab_uid, - const std::string& url) { - DictionaryValue value; - value.SetString(kCommandKey, DebuggerRemoteServiceCommand::kFrameNavigate); - value.SetInteger(kResultKey, RESULT_OK); - value.SetString(kDataKey, url); - SendResponse(value, kToolName, base::IntToString(tab_uid)); -} - -// Gets invoked from a DevToolsClientHost callback whenever -// a tab corresponding to |tab_id| gets closed. -// Sends the corresponding message to the remote debugger. -void DebuggerRemoteService::TabClosed(int32 tab_id) { - DictionaryValue value; - value.SetString(kCommandKey, DebuggerRemoteServiceCommand::kTabClosed); - value.SetInteger(kResultKey, RESULT_OK); - SendResponse(value, kToolName, base::IntToString(tab_id)); -} - -// 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; - base::StringToInt(destination, &tab_uid); - if (tab_uid < 0) { - // Bad tab_uid received from remote debugger (perhaps NaN) - response->SetInteger(kResultKey, 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(kResultKey, RESULT_UNKNOWN_TAB); - return; - } - TabContents* tab_contents = ToTabContents(tab_uid); - if (tab_contents == NULL) { - // No active tab contents with tab_uid - response->SetInteger(kResultKey, RESULT_UNKNOWN_TAB); - return; - } - RenderViewHost* target_host = tab_contents->render_view_host(); - DevToolsClientHost* client_host = - delegate_->inspectable_tab_proxy()->ClientHostForTabId(tab_uid); - if (client_host == NULL) { - client_host = - delegate_->inspectable_tab_proxy()->NewClientHost(tab_uid, this); - DevToolsManager* manager = DevToolsManager::GetInstance(); - if (manager != NULL) { - manager->RegisterDevToolsClientHostFor(target_host, client_host); - response->SetInteger(kResultKey, RESULT_OK); - } else { - response->SetInteger(kResultKey, RESULT_DEBUGGER_ERROR); - } - } else { - // DevToolsClientHost for this tab is already registered - response->SetInteger(kResultKey, RESULT_ILLEGAL_TAB_STATE); - } -} - -// 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; - base::StringToInt(destination, &tab_uid); - if (tab_uid == -1) { - // Bad tab_uid received from remote debugger (NaN) - if (response != NULL) { - response->SetInteger(kResultKey, RESULT_UNKNOWN_TAB); - } - return; - } - int result_code; - DevToolsClientHostImpl* client_host = - delegate_->inspectable_tab_proxy()->ClientHostForTabId(tab_uid); - if (client_host != NULL) { - client_host->CloseImpl(); - result_code = RESULT_OK; - } else { - // No client host registered for |tab_uid|. - result_code = RESULT_UNKNOWN_TAB; - } - if (response != NULL) { - response->SetInteger(kResultKey, 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(kResultKey, RESULT_UNKNOWN_TAB); - return true; - } - DevToolsManager* manager = DevToolsManager::GetInstance(); - if (manager == NULL) { - response->SetInteger(kResultKey, RESULT_DEBUGGER_ERROR); - return true; - } - TabContents* tab_contents = ToTabContents(tab_uid); - if (tab_contents == NULL) { - // Unknown tab_uid from remote debugger - response->SetInteger(kResultKey, 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(kResultKey, RESULT_ILLEGAL_TAB_STATE); - return true; - } - std::string v8_command; - DictionaryValue* v8_command_value; - content->GetDictionary(kDataKey, &v8_command_value); - base::JSONWriter::Write(v8_command_value, false, &v8_command); - manager->ForwardToDevToolsAgent( - client_host, DevToolsAgentMsg_DebuggerCommand(MSG_ROUTING_NONE, - 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(kResultKey, RESULT_UNKNOWN_TAB); - return true; - } - TabContents* tab_contents = ToTabContents(tab_uid); - if (tab_contents == NULL) { - // Unknown tab_uid from remote debugger - response->SetInteger(kResultKey, RESULT_UNKNOWN_TAB); - return true; - } - RenderViewHost* render_view_host = tab_contents->render_view_host(); - if (render_view_host == NULL) { - // No RenderViewHost - response->SetInteger(kResultKey, RESULT_UNKNOWN_TAB); - return true; - } - std::string javascript; - content->GetString(kDataKey, &javascript); - render_view_host->ExecuteJavascriptInWebFrame(string16(), - UTF8ToUTF16(javascript)); - return false; -} diff --git a/content/browser/debugger/debugger_remote_service.h b/content/browser/debugger/debugger_remote_service.h deleted file mode 100644 index 3a0bb9c..0000000 --- a/content/browser/debugger/debugger_remote_service.h +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file declares the DebuggerRemoteServiceCommand struct and the -// DebuggerRemoteService class which handles commands directed to the -// "V8Debugger" tool. -#ifndef CONTENT_BROWSER_DEBUGGER_DEBUGGER_REMOTE_SERVICE_H_ -#define CONTENT_BROWSER_DEBUGGER_DEBUGGER_REMOTE_SERVICE_H_ -#pragma once - -#include <string> - -#include "base/basictypes.h" -#include "content/browser/debugger/devtools_remote.h" - -class DevToolsProtocolHandler; -class DevToolsRemoteMessage; -class TabContents; - -namespace base { -class DictionaryValue; -class Value; -} - -// Contains constants for DebuggerRemoteService tool protocol commands -// (V8-related only). -struct DebuggerRemoteServiceCommand { - static const std::string kAttach; - static const std::string kDetach; - static const std::string kDebuggerCommand; - static const std::string kEvaluateJavascript; - static const std::string kFrameNavigate; // navigation event - static const std::string kTabClosed; // tab closing event -}; - -// Handles V8 debugger-related messages from the remote debugger (like -// attach to V8 debugger, detach from V8 debugger, send command to V8 debugger) -// and proxies JSON messages from V8 debugger to the remote debugger. -class DebuggerRemoteService : public DevToolsRemoteListener { - public: - // |delegate| (never NULL) is the protocol handler instance - // which dispatches messages to this service. The responses from the - // V8 VM debugger are routed back to |delegate|. - // The ownership of |delegate| is NOT transferred to this class. - explicit DebuggerRemoteService(DevToolsProtocolHandler* delegate); - - // Handles a JSON message from the tab_uid-associated V8 debugger. - void DebuggerOutput(int32 tab_uid, const std::string& message); - - // Handles a frame navigation event. - void FrameNavigate(int32 tab_uid, const std::string& url); - - // Handles a tab closing event. - void TabClosed(int32 tab_uid); - - // Detaches the remote debugger from the tab specified by |destination|. - // It is public so that we can detach from the tab on the remote debugger - // connection loss. - // If |response| is not NULL, the operation result will be written - // as the "result" field in |response|, otherwise the result - // will not be propagated back to the caller. - void DetachFromTab(const std::string& destination, - base::DictionaryValue* response); - - // DevToolsRemoteListener interface. - - // Processes |message| from the remote debugger, where the tool is - // "V8Debugger". Either sends the reply immediately or waits for an - // asynchronous response from the V8 debugger. - virtual void HandleMessage(const DevToolsRemoteMessage& message); - - // Gets invoked on the remote debugger [socket] connection loss. - // Notifies the InspectableTabProxy of the remote debugger detachment. - virtual void OnConnectionLost(); - - // Specifies a tool name ("V8Debugger") handled by this class. - static const std::string kToolName; - - private: - // Operation result returned in the "result" field. - typedef enum { - RESULT_OK = 0, - RESULT_ILLEGAL_TAB_STATE, - RESULT_UNKNOWN_TAB, - RESULT_DEBUGGER_ERROR, - RESULT_UNKNOWN_COMMAND - } Result; - - virtual ~DebuggerRemoteService(); - - // Attaches a remote debugger to the tab specified by |destination|. - // Writes the attachment result (one of Result enum values) into |response|. - void AttachToTab(const std::string& destination, - base::DictionaryValue* response); - - // Retrieves a WebContents instance for the specified |tab_uid| - // or NULL if no such tab is found or no WebContents instance - // corresponds to that tab. - TabContents* ToTabContents(int32 tab_uid); - - // Sends a JSON message with the |response| to the remote debugger. - // |tool| and |destination| are used as the respective header values. - void SendResponse(const base::Value& response, - const std::string& tool, - const std::string& destination); - - // Redirects a V8 debugger command from |content| to a V8 debugger associated - // with the |tab_uid| and writes the result into |response| if it becomes - // known immediately. - bool DispatchDebuggerCommand(int tab_uid, - base::DictionaryValue* content, - base::DictionaryValue* response); - - // Redirects a Javascript evaluation command from |content| to - // a V8 debugger associated with the |tab_uid| and writes the result - // into |response| if it becomes known immediately. - bool DispatchEvaluateJavascript(int tab_uid, - base::DictionaryValue* content, - base::DictionaryValue* response); - - // The delegate is used to get an InspectableTabProxy instance. - DevToolsProtocolHandler* delegate_; - DISALLOW_COPY_AND_ASSIGN(DebuggerRemoteService); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEBUGGER_REMOTE_SERVICE_H_ diff --git a/content/browser/debugger/devtools_client_host.h b/content/browser/debugger/devtools_client_host.h index 37de5cc..7296ce8 100644 --- a/content/browser/debugger/devtools_client_host.h +++ b/content/browser/debugger/devtools_client_host.h @@ -58,21 +58,21 @@ class DevToolsClientHost { // Default front-end implementation requests that the window representing // this client host is activated. - virtual void Activate() {} + virtual void RequestActivate() {} // Default front-end implementation requests that the window representing // this client host is (un)docked. - virtual void SetDocked(bool docked) {} + virtual void RequestSetDocked(bool docked) {} // Default front-end implementation requests that the window representing // this client host is closed. - virtual void Close() {} + virtual void RequestClose() {} // Default front-end implementation requests that the Save As dialog using // default save location is shown with |suggested_file_name| as the default // name and |content| as the data to save. - virtual void SaveAs(const std::string& suggested_file_name, - const std::string& content) {} + virtual void RequestSaveAs(const std::string& suggested_file_name, + const std::string& content) {} // Returns client (front-end) RenderViewHost implementation of this // client host if applicable. NULL otherwise. diff --git a/content/browser/debugger/devtools_handler.cc b/content/browser/debugger/devtools_handler.cc index b046954..9ac789d 100644 --- a/content/browser/debugger/devtools_handler.cc +++ b/content/browser/debugger/devtools_handler.cc @@ -60,32 +60,32 @@ void DevToolsHandler::OnForwardToClient(const IPC::Message& message) { void DevToolsHandler::OnActivateWindow() { DevToolsClientHost* client_host = GetOwnerClientHost(); if (client_host) - client_host->Activate(); + client_host->RequestActivate(); } void DevToolsHandler::OnCloseWindow() { DevToolsClientHost* client_host = GetOwnerClientHost(); if (client_host) - client_host->Close(); + client_host->RequestClose(); } void DevToolsHandler::OnRequestDockWindow() { DevToolsClientHost* client_host = GetOwnerClientHost(); if (client_host) - client_host->SetDocked(true); + client_host->RequestSetDocked(true); } void DevToolsHandler::OnRequestUndockWindow() { DevToolsClientHost* client_host = GetOwnerClientHost(); if (client_host) - client_host->SetDocked(false); + client_host->RequestSetDocked(false); } void DevToolsHandler::OnSaveAs(const std::string& file_name, const std::string& content) { DevToolsClientHost* client_host = GetOwnerClientHost(); if (client_host) - client_host->SaveAs(file_name, content); + client_host->RequestSaveAs(file_name, content); } void DevToolsHandler::OnRuntimePropertyChanged(const std::string& name, diff --git a/content/browser/debugger/devtools_protocol_handler.cc b/content/browser/debugger/devtools_protocol_handler.cc deleted file mode 100644 index 2fa23c0..0000000 --- a/content/browser/debugger/devtools_protocol_handler.cc +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/debugger/devtools_protocol_handler.h" - -#include "base/logging.h" -#include "content/browser/debugger/inspectable_tab_proxy.h" -#include "content/browser/debugger/debugger_remote_service.h" -#include "content/browser/debugger/devtools_remote_message.h" -#include "content/browser/debugger/devtools_remote_listen_socket.h" -#include "content/browser/debugger/devtools_remote_service.h" -#include "content/browser/debugger/extension_ports_remote_service.h" -#include "content/browser/browser_thread.h" - -// static -scoped_refptr<DevToolsProtocolHandler> DevToolsProtocolHandler::Start( - int port) { - scoped_refptr<DevToolsProtocolHandler> proto_handler = - new DevToolsProtocolHandler(port); - proto_handler->RegisterDestination( - new DevToolsRemoteService(proto_handler), - DevToolsRemoteService::kToolName); - proto_handler->RegisterDestination( - new DebuggerRemoteService(proto_handler), - DebuggerRemoteService::kToolName); - proto_handler->RegisterDestination( - new ExtensionPortsRemoteService(proto_handler), - ExtensionPortsRemoteService::kToolName); - proto_handler->Start(); - return proto_handler; -} - -DevToolsProtocolHandler::DevToolsProtocolHandler(int port) - : port_(port), - connection_(NULL), - server_(NULL) { - inspectable_tab_proxy_.reset(new InspectableTabProxy); -} - -DevToolsProtocolHandler::~DevToolsProtocolHandler() { - // Stop() must be called prior to this being called - DCHECK(server_.get() == NULL); - DCHECK(connection_.get() == NULL); -} - -void DevToolsProtocolHandler::Start() { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, &DevToolsProtocolHandler::Init)); -} - -void DevToolsProtocolHandler::Init() { - server_ = DevToolsRemoteListenSocket::Listen( - "127.0.0.1", port_, this); -} - -void DevToolsProtocolHandler::Stop() { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, &DevToolsProtocolHandler::Teardown)); - tool_to_listener_map_.clear(); // Releases all scoped_refptr's to listeners -} - -// Run in I/O thread -void DevToolsProtocolHandler::Teardown() { - connection_ = NULL; - server_ = NULL; -} - -void DevToolsProtocolHandler::RegisterDestination( - DevToolsRemoteListener* listener, - const std::string& tool_name) { - DCHECK(tool_to_listener_map_.find(tool_name) == tool_to_listener_map_.end()); - tool_to_listener_map_.insert(std::make_pair(tool_name, listener)); -} - -void DevToolsProtocolHandler::UnregisterDestination( - DevToolsRemoteListener* listener, - const std::string& tool_name) { - DCHECK(tool_to_listener_map_.find(tool_name) != tool_to_listener_map_.end()); - DCHECK(tool_to_listener_map_.find(tool_name)->second == listener); - tool_to_listener_map_.erase(tool_name); -} - -void DevToolsProtocolHandler::HandleMessage( - const DevToolsRemoteMessage& message) { - std::string tool = message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kTool); - ToolToListenerMap::const_iterator it = tool_to_listener_map_.find(tool); - if (it == tool_to_listener_map_.end()) { - NOTREACHED(); // an unsupported tool, bail out - return; - } - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - it->second.get(), &DevToolsRemoteListener::HandleMessage, message)); -} - -void DevToolsProtocolHandler::Send(const DevToolsRemoteMessage& message) { - if (connection_ != NULL) { - connection_->Send(message.ToString()); - } -} - -void DevToolsProtocolHandler::OnAcceptConnection( - net::ListenSocket *connection) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - connection_ = connection; -} - -void DevToolsProtocolHandler::OnConnectionLost() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - connection_ = NULL; - for (ToolToListenerMap::const_iterator it = tool_to_listener_map_.begin(), - end = tool_to_listener_map_.end(); - it != end; - ++it) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - NewRunnableMethod( - it->second.get(), &DevToolsRemoteListener::OnConnectionLost)); - } -} diff --git a/content/browser/debugger/devtools_protocol_handler.h b/content/browser/debugger/devtools_protocol_handler.h deleted file mode 100644 index 668ca94..0000000 --- a/content/browser/debugger/devtools_protocol_handler.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_DEBUGGER_DEVTOOLS_PROTOCOL_HANDLER_H_ -#define CONTENT_BROWSER_DEBUGGER_DEVTOOLS_PROTOCOL_HANDLER_H_ -#pragma once - -#include <string> - -#include "base/hash_tables.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "content/browser/debugger/devtools_remote.h" -#include "net/base/listen_socket.h" - -class InspectableTabProxy; -class DevToolsRemoteListenSocket; -class DevToolsRemoteMessage; - -// Dispatches DevToolsRemoteMessages to their appropriate handlers (Tools) -// based on the "Tool" message header value. -class DevToolsProtocolHandler - : public DevToolsRemoteListener, - public OutboundSocketDelegate { - public: - typedef base::hash_map< std::string, scoped_refptr<DevToolsRemoteListener> > - ToolToListenerMap; - - static scoped_refptr<DevToolsProtocolHandler> Start(int port); - - // Called from the main thread in order to stop protocol handler. - // Will schedule tear down task on IO thread. - void Stop(); - - // Registers a |listener| to handle messages for a certain |tool_name| Tool. - // |listener| is the new message handler to register. - // As DevToolsRemoteListener inherits base::RefCountedThreadSafe, - // you should have no problems with ownership and destruction. - // |tool_name| is the name of the Tool to associate the listener with. - void RegisterDestination(DevToolsRemoteListener* listener, - const std::string& tool_name); - - // Unregisters a |listener| so that it will no longer handle messages - // directed to the specified |tool_name| tool. - void UnregisterDestination(DevToolsRemoteListener* listener, - const std::string& tool_name); - - InspectableTabProxy* inspectable_tab_proxy() { - return inspectable_tab_proxy_.get(); - } - - // DevToolsRemoteListener interface - virtual void HandleMessage(const DevToolsRemoteMessage& message); - virtual void OnAcceptConnection(net::ListenSocket *connection); - virtual void OnConnectionLost(); - - // OutboundSocketDelegate interface - virtual void Send(const DevToolsRemoteMessage& message); - - private: - explicit DevToolsProtocolHandler(int port); - virtual ~DevToolsProtocolHandler(); - void Start(); - - void Init(); - void Teardown(); - int port_; - ToolToListenerMap tool_to_listener_map_; - scoped_refptr<net::ListenSocket> connection_; - scoped_refptr<DevToolsRemoteListenSocket> server_; - scoped_ptr<InspectableTabProxy> inspectable_tab_proxy_; - DISALLOW_COPY_AND_ASSIGN(DevToolsProtocolHandler); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEVTOOLS_PROTOCOL_HANDLER_H_ diff --git a/content/browser/debugger/devtools_remote.h b/content/browser/debugger/devtools_remote.h deleted file mode 100644 index cb6f41d..0000000 --- a/content/browser/debugger/devtools_remote.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_H_ -#define CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" - -class DevToolsRemoteMessage; - -namespace net { -class ListenSocket; -} - -// This interface should be implemented by a class that wants to handle -// DevToolsRemoteMessages dispatched by some entity. It must extend -class DevToolsRemoteListener - : public base::RefCountedThreadSafe<DevToolsRemoteListener> { - public: - DevToolsRemoteListener() {} - virtual void HandleMessage(const DevToolsRemoteMessage& message) = 0; - // This method is invoked on the UI thread whenever the debugger connection - // has been lost. - virtual void OnConnectionLost() = 0; - virtual void OnAcceptConnection(net::ListenSocket* connection) {} - - protected: - friend class base::RefCountedThreadSafe<DevToolsRemoteListener>; - - virtual ~DevToolsRemoteListener() {} - - private: - DISALLOW_COPY_AND_ASSIGN(DevToolsRemoteListener); -}; - -// Interface exposed by DevToolsProtocolHandler to receive reply messages -// from registered tools. -class OutboundSocketDelegate { - public: - virtual ~OutboundSocketDelegate() {} - virtual void Send(const DevToolsRemoteMessage& message) = 0; -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_H_ diff --git a/content/browser/debugger/devtools_remote_listen_socket.cc b/content/browser/debugger/devtools_remote_listen_socket.cc deleted file mode 100644 index 5e7831f..0000000 --- a/content/browser/debugger/devtools_remote_listen_socket.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/debugger/devtools_remote_listen_socket.h" - -#include "build/build_config.h" - -#include <stdlib.h> - -#if defined(OS_WIN) -// winsock2.h must be included first in order to ensure it is included before -// windows.h. -#include <winsock2.h> -#elif defined(OS_POSIX) -#include <errno.h> -#include <sys/socket.h> -#endif - -#include "base/compiler_specific.h" -#include "base/eintr_wrapper.h" -#include "base/string_number_conversions.h" -#include "base/threading/platform_thread.h" -#include "content/browser/debugger/devtools_remote.h" -#include "content/browser/debugger/devtools_remote_message.h" - -#define CONSUME_BUFFER_CHAR \ - pBuf++;\ - len-- - -#if defined(OS_POSIX) -// Used same name as in Windows to avoid #ifdef where refrenced -#define SOCKET int -const int INVALID_SOCKET = -1; -const int SOCKET_ERROR = -1; -#endif - -const int kReadBufSize = 200; - -DevToolsRemoteListenSocket::DevToolsRemoteListenSocket( - SOCKET s, - DevToolsRemoteListener* message_listener) - : ALLOW_THIS_IN_INITIALIZER_LIST(net::ListenSocket(s, this)), - state_(HANDSHAKE), - remaining_payload_length_(0), - message_listener_(message_listener), - cr_received_(false) {} - -void DevToolsRemoteListenSocket::StartNextField() { - switch (state_) { - case INVALID: - state_ = HANDSHAKE; - break; - case HANDSHAKE: - state_ = HEADERS; - break; - case HEADERS: - if (protocol_field_.empty()) { // empty line - end of headers - const std::string& payload_length_string = GetHeader( - DevToolsRemoteMessageHeaders::kContentLength, "0"); - base::StringToInt(payload_length_string, &remaining_payload_length_); - state_ = PAYLOAD; - if (remaining_payload_length_ == 0) { // no payload - DispatchField(); - return; - } - } - break; - case PAYLOAD: - header_map_.clear(); - payload_.clear(); - state_ = HEADERS; - break; - default: - NOTREACHED(); - break; - } - protocol_field_.clear(); -} - -DevToolsRemoteListenSocket::~DevToolsRemoteListenSocket() {} - -DevToolsRemoteListenSocket* - DevToolsRemoteListenSocket::Listen(const std::string& ip, - int port, - DevToolsRemoteListener* listener) { - SOCKET s = net::ListenSocket::Listen(ip, port); - if (s == INVALID_SOCKET) { - // TODO(apavlov): error handling - } else { - DevToolsRemoteListenSocket* sock = - new DevToolsRemoteListenSocket(s, listener); - sock->Listen(); - return sock; - } - return NULL; -} - -void DevToolsRemoteListenSocket::DidAccept(net::ListenSocket *server, - net::ListenSocket *connection) { - connection->AddRef(); - message_listener_->OnAcceptConnection(connection); -} - -// Dispatches data from socket to socket_delegate_, extracting messages -// delimited by newlines. -void DevToolsRemoteListenSocket::DidRead(net::ListenSocket* connection, - const char* pBuf, - int len) { - while (len > 0) { - if (state_ != PAYLOAD) { - if (cr_received_ && *pBuf == '\n') { - cr_received_ = false; - CONSUME_BUFFER_CHAR; - } else { - while (*pBuf != '\r' && len > 0) { - protocol_field_.push_back(*pBuf); - CONSUME_BUFFER_CHAR; - } - if (*pBuf == '\r') { - cr_received_ = true; - CONSUME_BUFFER_CHAR; - } - continue; - } - switch (state_) { - case HANDSHAKE: - case HEADERS: - DispatchField(); - break; - default: - NOTREACHED(); - break; - } - } else { // PAYLOAD - while (remaining_payload_length_ > 0 && len > 0) { - protocol_field_.push_back(*pBuf); - CONSUME_BUFFER_CHAR; - remaining_payload_length_--; - } - if (remaining_payload_length_ == 0) { - DispatchField(); - } - } - } -} - -void DevToolsRemoteListenSocket::DidClose(net::ListenSocket *connection) { - message_listener_->OnConnectionLost(); - connection->Release(); -} - -void DevToolsRemoteListenSocket::DispatchField() { - static const std::string kHandshakeString = "ChromeDevToolsHandshake"; - switch (state_) { - case HANDSHAKE: - if (protocol_field_.compare(kHandshakeString)) { - state_ = INVALID; - } else { - Send(kHandshakeString, true); - } - break; - case HEADERS: { - if (!protocol_field_.empty()) { // not end-of-headers - std::string::size_type colon_pos = protocol_field_.find_first_of(":"); - if (colon_pos == std::string::npos) { - // TODO(apavlov): handle the error (malformed header) - } else { - const std::string header_name = protocol_field_.substr(0, colon_pos); - std::string header_val = protocol_field_.substr(colon_pos + 1); - header_map_[header_name] = header_val; - } - } - break; - } - case PAYLOAD: - payload_ = protocol_field_; - HandleMessage(); - break; - default: - NOTREACHED(); - break; - } - StartNextField(); -} - -const std::string& DevToolsRemoteListenSocket::GetHeader( - const std::string& header_name, - const std::string& default_value) const { - DevToolsRemoteMessage::HeaderMap::const_iterator it = - header_map_.find(header_name); - if (it == header_map_.end()) { - return default_value; - } - return it->second; -} - -// Handle header_map_ and payload_ -void DevToolsRemoteListenSocket::HandleMessage() { - if (message_listener_ != NULL) { - DevToolsRemoteMessage message(header_map_, payload_); - message_listener_->HandleMessage(message); - } -} - -void DevToolsRemoteListenSocket::Listen() { - net::ListenSocket::Listen(); -} - -void DevToolsRemoteListenSocket::Accept() { - SOCKET conn = net::ListenSocket::Accept(socket_); - if (conn != INVALID_SOCKET) { - scoped_refptr<DevToolsRemoteListenSocket> sock( - new DevToolsRemoteListenSocket(conn, - message_listener_)); - // it's up to the delegate to AddRef if it wants to keep it around -#if defined(OS_POSIX) - sock->WatchSocket(WAITING_READ); -#endif - socket_delegate_->DidAccept(this, sock); - } else { - // TODO(apavlov): some error handling required here - } -} - -void DevToolsRemoteListenSocket::SendInternal(const char* bytes, int len) { - char* send_buf = const_cast<char *>(bytes); - int len_left = len; - while (true) { - int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); - if (sent == len_left) { // A shortcut to avoid extraneous checks. - break; - } - if (sent == kSocketError) { -#if defined(OS_WIN) - if (WSAGetLastError() != WSAEWOULDBLOCK) { - LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); -#elif defined(OS_POSIX) - if (errno != EWOULDBLOCK && errno != EAGAIN) { - LOG(ERROR) << "send failed: errno==" << errno; -#endif - break; - } - // Otherwise we would block, and now we have to wait for a retry. - // Fall through to PlatformThread::YieldCurrentThread() - } else { - // sent != len_left according to the shortcut above. - // Shift the buffer start and send the remainder after a short while. - send_buf += sent; - len_left -= sent; - } - base::PlatformThread::YieldCurrentThread(); - } -} - -void DevToolsRemoteListenSocket::Close() { - net::ListenSocket::Close(); -} diff --git a/content/browser/debugger/devtools_remote_listen_socket.h b/content/browser/debugger/devtools_remote_listen_socket.h deleted file mode 100644 index 60d49c6..0000000 --- a/content/browser/debugger/devtools_remote_listen_socket.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_H_ -#define CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_H_ -#pragma once - -#include <string> - -#include "content/browser/debugger/devtools_remote_message.h" -#include "net/base/listen_socket.h" - -class DevToolsRemoteListener; - -// Listens to remote debugger incoming connections, handles the V8ARDP protocol -// socket input and invokes the message handler when appropriate. -class DevToolsRemoteListenSocket - : public net::ListenSocket, - public net::ListenSocket::ListenSocketDelegate { - public: - // Listen on port for the specified IP address. Use 127.0.0.1 to only - // accept local connections. - static DevToolsRemoteListenSocket* Listen( - const std::string& ip, - int port, - DevToolsRemoteListener* message_listener); - - protected: - virtual void Listen(); - virtual void Accept(); - virtual void Close(); - virtual void SendInternal(const char* bytes, int len); - - private: - virtual ~DevToolsRemoteListenSocket(); - - // net::ListenSocket::ListenSocketDelegate interface - virtual void DidAccept(net::ListenSocket *server, - net::ListenSocket *connection); - virtual void DidRead(net::ListenSocket *connection, - const char* data, int len); - virtual void DidClose(net::ListenSocket *connection); - - // The protocol states while reading socket input - enum State { - INVALID = 0, // Bad handshake message received, retry - HANDSHAKE = 1, // Receiving handshake message - HEADERS = 2, // Receiving protocol headers - PAYLOAD = 3 // Receiving payload - }; - - DevToolsRemoteListenSocket(SOCKET s, - DevToolsRemoteListener *listener); - void StartNextField(); - void HandleMessage(); - void DispatchField(); - const std::string& GetHeader(const std::string& header_name, - const std::string& default_value) const; - - State state_; - DevToolsRemoteMessage::HeaderMap header_map_; - std::string protocol_field_; - std::string payload_; - int32 remaining_payload_length_; - DevToolsRemoteListener* message_listener_; - bool cr_received_; - - DISALLOW_COPY_AND_ASSIGN(DevToolsRemoteListenSocket); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_H_ diff --git a/content/browser/debugger/devtools_remote_listen_socket_unittest.cc b/content/browser/debugger/devtools_remote_listen_socket_unittest.cc deleted file mode 100644 index 348fdbb..0000000 --- a/content/browser/debugger/devtools_remote_listen_socket_unittest.cc +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/debugger/devtools_remote_listen_socket_unittest.h" - -#include <fcntl.h> -#if defined(OS_POSIX) -#include <netinet/in.h> -#endif - -#include "base/eintr_wrapper.h" -#include "base/test/test_timeouts.h" -#include "base/threading/platform_thread.h" -#include "net/base/net_util.h" -#include "testing/platform_test.h" - -const int DevToolsRemoteListenSocketTester::kTestPort = 9999; - -static const int kReadBufSize = 1024; -static const char* kChromeDevToolsHandshake = "ChromeDevToolsHandshake\r\n"; -static const char* kSimpleMessagePart1 = - "Tool:V8Debugger\r\n" - "Destination:2\r"; -static const char* kSimpleMessagePart2 = - "\n" - "Content-Length:0\r\n" - "\r\n"; -static const char* kTwoMessages = - "Tool:DevToolsService\r\n" - "Content-Length:300\r\n" - "\r\n" - "00000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000000000" - "Tool:V8Debugger\r\n" - "Destination:1\r\n" - "Content-Length:0\r\n" - "\r\n"; - -static const int kMaxQueueSize = 20; -static const char* kLoopback = "127.0.0.1"; -#if defined(OS_POSIX) -static const char* kSemaphoreName = "chromium.listen_socket"; -#endif - - -ListenSocketTestAction::ListenSocketTestAction() : action_(ACTION_NONE) {} - -ListenSocketTestAction::ListenSocketTestAction(ActionType action) - : action_(action) {} - -ListenSocketTestAction::ListenSocketTestAction(ActionType action, - std::string data) - : action_(action), - data_(data) {} - -ListenSocketTestAction::ListenSocketTestAction( - ActionType action, - const DevToolsRemoteMessage& message) - : action_(action), - message_(message) {} - -ListenSocketTestAction::~ListenSocketTestAction() {} - -net::ListenSocket* DevToolsRemoteListenSocketTester::DoListen() { - return DevToolsRemoteListenSocket::Listen(kLoopback, kTestPort, this); -} - -DevToolsRemoteListenSocketTester::DevToolsRemoteListenSocketTester() - : semaphore_(NULL), - thread_(NULL), - loop_(NULL), - server_(NULL), - connection_(NULL), - test_socket_(INVALID_SOCKET) { - memset(&lock_, 0, sizeof(lock_)); -} - -void DevToolsRemoteListenSocketTester::SetUp() { -#if defined(OS_WIN) - InitializeCriticalSection(&lock_); - semaphore_ = CreateSemaphore(NULL, 0, kMaxQueueSize, NULL); - server_ = NULL; - net::EnsureWinsockInit(); -#elif defined(OS_POSIX) - ASSERT_EQ(0, pthread_mutex_init(&lock_, NULL)); - sem_unlink(kSemaphoreName); - semaphore_ = sem_open(kSemaphoreName, O_CREAT, 0, 0); - ASSERT_NE(SEM_FAILED, semaphore_); -#endif - base::Thread::Options options; - options.message_loop_type = MessageLoop::TYPE_IO; - thread_.reset(new base::Thread("socketio_test")); - thread_->StartWithOptions(options); - loop_ = static_cast<MessageLoopForIO*>(thread_->message_loop()); - - loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &DevToolsRemoteListenSocketTester::Listen)); - - // verify Listen succeeded - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_FALSE(server_ == NULL); - ASSERT_EQ(ACTION_LISTEN, last_action_.type()); - - // verify the connect/accept and setup test_socket_ - test_socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - ASSERT_NE(INVALID_SOCKET, test_socket_); - struct sockaddr_in client; - client.sin_family = AF_INET; - client.sin_addr.s_addr = inet_addr(kLoopback); - client.sin_port = htons(kTestPort); - int ret = HANDLE_EINTR(connect(test_socket_, - reinterpret_cast<sockaddr*>(&client), - sizeof(client))); - ASSERT_NE(ret, SOCKET_ERROR); - - net::SetNonBlocking(test_socket_); - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_EQ(ACTION_ACCEPT, last_action_.type()); -} - -void DevToolsRemoteListenSocketTester::TearDown() { - // verify close -#if defined(OS_WIN) - closesocket(test_socket_); -#elif defined(OS_POSIX) - int ret = HANDLE_EINTR(close(test_socket_)); - ASSERT_EQ(ret, 0); -#endif - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_EQ(ACTION_CLOSE, last_action_.type()); - - loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &DevToolsRemoteListenSocketTester::Shutdown)); - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_EQ(ACTION_SHUTDOWN, last_action_.type()); - -#if defined(OS_WIN) - CloseHandle(semaphore_); - semaphore_ = 0; - DeleteCriticalSection(&lock_); -#elif defined(OS_POSIX) - ASSERT_EQ(0, pthread_mutex_lock(&lock_)); - semaphore_ = NULL; - ASSERT_EQ(0, pthread_mutex_unlock(&lock_)); - ASSERT_EQ(0, sem_unlink(kSemaphoreName)); - ASSERT_EQ(0, pthread_mutex_destroy(&lock_)); -#endif - - thread_.reset(); - loop_ = NULL; -} - -void DevToolsRemoteListenSocketTester::ReportAction( - const ListenSocketTestAction& action) { -#if defined(OS_WIN) - EnterCriticalSection(&lock_); - queue_.push_back(action); - LeaveCriticalSection(&lock_); - ReleaseSemaphore(semaphore_, 1, NULL); -#elif defined(OS_POSIX) - ASSERT_EQ(0, pthread_mutex_lock(&lock_)); - queue_.push_back(action); - ASSERT_EQ(0, pthread_mutex_unlock(&lock_)); - ASSERT_EQ(0, sem_post(semaphore_)); -#endif -} - -bool DevToolsRemoteListenSocketTester::NextAction(int timeout) { -#if defined(OS_WIN) - DWORD ret = ::WaitForSingleObject(semaphore_, timeout); - if (ret != WAIT_OBJECT_0) - return false; - EnterCriticalSection(&lock_); - if (queue_.empty()) { - LeaveCriticalSection(&lock_); - return false; - } - last_action_ = queue_.front(); - queue_.pop_front(); - LeaveCriticalSection(&lock_); - return true; -#elif defined(OS_POSIX) - if (semaphore_ == SEM_FAILED) - return false; - while (true) { - int result = sem_trywait(semaphore_); - base::PlatformThread::Sleep(1); // 1MS sleep - timeout--; - if (timeout <= 0) - return false; - if (result == 0) - break; - } - pthread_mutex_lock(&lock_); - if (queue_.empty()) { - pthread_mutex_unlock(&lock_); - return false; - } - last_action_ = queue_.front(); - queue_.pop_front(); - pthread_mutex_unlock(&lock_); - return true; -#endif -} - -int DevToolsRemoteListenSocketTester::ClearTestSocket() { - char buf[kReadBufSize]; - int len_ret = 0; - int time_out = 0; - do { - int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0)); -#if defined(OS_WIN) - if (len == SOCKET_ERROR) { - int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { -#elif defined(OS_POSIX) - if (len == SOCKET_ERROR) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { -#endif - base::PlatformThread::Sleep(1); - time_out++; - if (time_out > 10) - break; - continue; // still trying - } - } else if (len == 0) { - // socket closed - break; - } else { - time_out = 0; - len_ret += len; - } - } while (true); - return len_ret; -} - -void DevToolsRemoteListenSocketTester::Shutdown() { - server_->Release(); - server_ = NULL; - ReportAction(ListenSocketTestAction(ACTION_SHUTDOWN)); -} - -void DevToolsRemoteListenSocketTester::Listen() { - server_ = DoListen(); - server_->AddRef(); - ReportAction(ListenSocketTestAction(ACTION_LISTEN)); -} - -void DevToolsRemoteListenSocketTester::SendFromTester() { - connection_->Send(kChromeDevToolsHandshake); - ReportAction(ListenSocketTestAction(ACTION_SEND)); -} - -void DevToolsRemoteListenSocketTester::OnAcceptConnection( - net::ListenSocket* connection) { - connection_ = connection; - ReportAction(ListenSocketTestAction(ACTION_ACCEPT)); -} - -void DevToolsRemoteListenSocketTester::OnConnectionLost() { - connection_ = NULL; - ReportAction(ListenSocketTestAction(ACTION_CLOSE)); -} - -void DevToolsRemoteListenSocketTester::HandleMessage( - const DevToolsRemoteMessage& message) { - ReportAction(ListenSocketTestAction(ACTION_READ_MESSAGE, message)); -} - -bool DevToolsRemoteListenSocketTester::Send(SOCKET sock, - const std::string& str) { - int len = static_cast<int>(str.length()); - int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0)); - if (send_len == SOCKET_ERROR) { - LOG(ERROR) << "send failed: " << errno; - return false; - } else if (send_len != len) { - return false; - } - return true; -} - -void DevToolsRemoteListenSocketTester::TestClientSend() { - ASSERT_TRUE(Send(test_socket_, kChromeDevToolsHandshake)); - { - ASSERT_TRUE(Send(test_socket_, kSimpleMessagePart1)); - // sleep for 10ms to test message split between \r and \n - base::PlatformThread::Sleep(10); - ASSERT_TRUE(Send(test_socket_, kSimpleMessagePart2)); - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_EQ(ACTION_READ_MESSAGE, last_action_.type()); - const DevToolsRemoteMessage& message = last_action_.message(); - ASSERT_STREQ("V8Debugger", message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kTool).c_str()); - ASSERT_STREQ("2", message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kDestination).c_str()); - ASSERT_STREQ("0", message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kContentLength).c_str()); - ASSERT_EQ(0, static_cast<int>(message.content().size())); - } - ASSERT_TRUE(Send(test_socket_, kTwoMessages)); - { - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_EQ(ACTION_READ_MESSAGE, last_action_.type()); - const DevToolsRemoteMessage& message = last_action_.message(); - ASSERT_STREQ("DevToolsService", message.tool().c_str()); - ASSERT_STREQ("", message.destination().c_str()); - ASSERT_EQ(300, message.content_length()); - const std::string& content = message.content(); - ASSERT_EQ(300, static_cast<int>(content.size())); - for (int i = 0; i < 300; ++i) { - ASSERT_EQ('0', content[i]); - } - } - { - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_EQ(ACTION_READ_MESSAGE, last_action_.type()); - const DevToolsRemoteMessage& message = last_action_.message(); - ASSERT_STREQ("V8Debugger", message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kTool).c_str()); - ASSERT_STREQ("1", message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kDestination).c_str()); - ASSERT_STREQ("0", message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kContentLength).c_str()); - const std::string& content = message.content(); - ASSERT_EQ(0, static_cast<int>(content.size())); - } -} - -void DevToolsRemoteListenSocketTester::TestServerSend() { - loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &DevToolsRemoteListenSocketTester::SendFromTester)); - ASSERT_TRUE(NextAction(TestTimeouts::action_timeout_ms())); - ASSERT_EQ(ACTION_SEND, last_action_.type()); - // TODO(erikkay): Without this sleep, the recv seems to fail a small amount - // of the time. I could fix this by making the socket blocking, but then - // this test might hang in the case of errors. It would be nice to do - // something that felt more reliable here. - base::PlatformThread::Sleep(10); // sleep for 10ms - const int buf_len = 200; - char buf[buf_len+1]; - int recv_len = HANDLE_EINTR(recv(test_socket_, buf, buf_len, 0)); - ASSERT_NE(recv_len, SOCKET_ERROR); - buf[recv_len] = 0; - ASSERT_STREQ(buf, kChromeDevToolsHandshake); -} - -DevToolsRemoteListenSocketTester::~DevToolsRemoteListenSocketTester() {} - -class DevToolsRemoteListenSocketTest: public PlatformTest { - public: - DevToolsRemoteListenSocketTest() { - tester_ = NULL; - } - - virtual void SetUp() { - PlatformTest::SetUp(); - tester_ = new DevToolsRemoteListenSocketTester(); - tester_->SetUp(); - } - - virtual void TearDown() { - PlatformTest::TearDown(); - tester_->TearDown(); - tester_ = NULL; - } - - scoped_refptr<DevToolsRemoteListenSocketTester> tester_; -}; - -// This test is flaky; see comment in ::TestServerSend. -TEST_F(DevToolsRemoteListenSocketTest, ServerSend) { - tester_->TestServerSend(); -} - -TEST_F(DevToolsRemoteListenSocketTest, ClientSend) { - tester_->TestClientSend(); -} diff --git a/content/browser/debugger/devtools_remote_listen_socket_unittest.h b/content/browser/debugger/devtools_remote_listen_socket_unittest.h deleted file mode 100644 index a601544d..0000000 --- a/content/browser/debugger/devtools_remote_listen_socket_unittest.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_UNITTEST_H_ -#define CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_UNITTEST_H_ -#pragma once - -#include "build/build_config.h" - -#include <deque> -#include <string> - -#if defined(OS_WIN) -#include <winsock2.h> -#elif defined(OS_POSIX) -#include <sys/socket.h> -#include <errno.h> -#include <semaphore.h> -#include <arpa/inet.h> -#endif - -#include "base/threading/thread.h" -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "base/string_util.h" -#include "base/threading/thread.h" -#include "content/browser/debugger/devtools_remote.h" -#include "content/browser/debugger/devtools_remote_listen_socket.h" -#include "content/browser/debugger/devtools_remote_message.h" -#include "net/base/net_util.h" -#include "net/base/listen_socket.h" -#include "net/base/winsock_init.h" -#include "testing/gtest/include/gtest/gtest.h" - -#if defined(OS_POSIX) -// Used same name as in Windows to avoid #ifdef where refrenced -#define SOCKET int -const int INVALID_SOCKET = -1; -const int SOCKET_ERROR = -1; -#endif - -enum ActionType { - ACTION_NONE = 0, - ACTION_LISTEN = 1, - ACTION_ACCEPT = 2, - ACTION_READ = 3, - ACTION_READ_MESSAGE = 4, - ACTION_SEND = 5, - ACTION_CLOSE = 6, - ACTION_SHUTDOWN = 7 -}; - -class ListenSocketTestAction { - public: - ListenSocketTestAction(); - explicit ListenSocketTestAction(ActionType action); - ListenSocketTestAction(ActionType action, std::string data); - ListenSocketTestAction(ActionType action, - const DevToolsRemoteMessage& message); - ~ListenSocketTestAction(); - - const std::string data() const { return data_; } - const DevToolsRemoteMessage message() { return message_; } - ActionType type() const { return action_; } - - private: - ActionType action_; - std::string data_; - DevToolsRemoteMessage message_; -}; - - -// This had to be split out into a separate class because I couldn't -// make a the testing::Test class refcounted. -class DevToolsRemoteListenSocketTester : - public DevToolsRemoteListener { - public: - DevToolsRemoteListenSocketTester(); - - virtual void SetUp(); - virtual void TearDown(); - - void ReportAction(const ListenSocketTestAction& action); - bool NextAction(int timeout); - - // DevToolsRemoteMessageHandler interface - virtual void HandleMessage(const DevToolsRemoteMessage& message); - virtual void OnAcceptConnection(net::ListenSocket* connection); - virtual void OnConnectionLost(); - - // read all pending data from the test socket - int ClearTestSocket(); - // Release the connection and server sockets - void Shutdown(); - void Listen(); - void SendFromTester(); - virtual bool Send(SOCKET sock, const std::string& str); - // verify the send/read from client to server - void TestClientSend(); - // verify a send/read from server to client - void TestServerSend(); - -#if defined(OS_WIN) - CRITICAL_SECTION lock_; - HANDLE semaphore_; -#elif defined(OS_POSIX) - pthread_mutex_t lock_; - sem_t* semaphore_; -#endif - - scoped_ptr<base::Thread> thread_; - MessageLoopForIO* loop_; - net::ListenSocket* server_; - net::ListenSocket* connection_; - ListenSocketTestAction last_action_; - std::deque<ListenSocketTestAction> queue_; - SOCKET test_socket_; - static const int kTestPort; - - protected: - virtual net::ListenSocket* DoListen(); - - private: - virtual ~DevToolsRemoteListenSocketTester(); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_LISTEN_SOCKET_UNITTEST_H_ diff --git a/content/browser/debugger/devtools_remote_message.cc b/content/browser/debugger/devtools_remote_message.cc deleted file mode 100644 index 3b6a6ab..0000000 --- a/content/browser/debugger/devtools_remote_message.cc +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/debugger/devtools_remote_message.h" - -#include "base/string_number_conversions.h" - -const char DevToolsRemoteMessageHeaders::kContentLength[] = "Content-Length"; -const char DevToolsRemoteMessageHeaders::kTool[] = "Tool"; -const char DevToolsRemoteMessageHeaders::kDestination[] = "Destination"; - -const char DevToolsRemoteMessage::kEmptyValue[] = ""; - -DevToolsRemoteMessageBuilder& DevToolsRemoteMessageBuilder::instance() { - static DevToolsRemoteMessageBuilder instance_; - return instance_; -} - -DevToolsRemoteMessage::DevToolsRemoteMessage() {} - -DevToolsRemoteMessage::DevToolsRemoteMessage(const HeaderMap& headers, - const std::string& content) - : header_map_(headers), - content_(content) { -} - -DevToolsRemoteMessage::~DevToolsRemoteMessage() {} - -const std::string DevToolsRemoteMessage::GetHeader( - const std::string& header_name, - const std::string& default_value) const { - HeaderMap::const_iterator it = header_map_.find(header_name); - if (it == header_map_.end()) { - return default_value; - } - return it->second; -} - -const std::string DevToolsRemoteMessage::GetHeaderWithEmptyDefault( - const std::string& header_name) const { - return GetHeader(header_name, DevToolsRemoteMessage::kEmptyValue); -} - -const std::string DevToolsRemoteMessage::ToString() const { - std::string result; - for (HeaderMap::const_iterator it = header_map_.begin(), - end = header_map_.end(); it != end; ++it) { - result.append(it->first).append(":").append(it->second).append("\r\n"); - } - result.append("\r\n").append(content_); - return result; -} - -DevToolsRemoteMessage* DevToolsRemoteMessageBuilder::Create( - const std::string& tool, - const std::string& destination, - const std::string& content) { - DevToolsRemoteMessage::HeaderMap headers; - headers[DevToolsRemoteMessageHeaders::kContentLength] = - base::IntToString(content.size()); - headers[DevToolsRemoteMessageHeaders::kTool] = tool; - headers[DevToolsRemoteMessageHeaders::kDestination] = destination; - return new DevToolsRemoteMessage(headers, content); -} diff --git a/content/browser/debugger/devtools_remote_message.h b/content/browser/debugger/devtools_remote_message.h deleted file mode 100644 index 75bbad4..0000000 --- a/content/browser/debugger/devtools_remote_message.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_MESSAGE_H_ -#define CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_MESSAGE_H_ -#pragma once - -#include <string> - -#include "base/basictypes.h" -#include "base/hash_tables.h" - -// Contains DevTools protocol message header names -// and the Flags header bit field constants. -struct DevToolsRemoteMessageHeaders { - // The content length in decimal. - static const char kContentLength[]; - // The tool that should handle the message. - static const char kTool[]; - // The destination (inspected) object identifier (if any), like a TabID. - static const char kDestination[]; -}; - -// Represents a Chrome remote debugging protocol message transferred -// over the wire between the remote debugger and a Chrome instance. -// Consider using DevToolsRemoteMessageBuilder (see end of this file) for easy -// construction of outbound (Chrome -> remote debugger) messages. -class DevToolsRemoteMessage { - public: - typedef base::hash_map<std::string, std::string> HeaderMap; - - // Use this as the second parameter in a |GetHeader| call to use - // an empty string as the default value. - static const char kEmptyValue[]; - - // Constructs an empty message with no content or headers. - DevToolsRemoteMessage(); - DevToolsRemoteMessage(const HeaderMap& headers, const std::string& content); - virtual ~DevToolsRemoteMessage(); - - const HeaderMap& headers() const { - return header_map_; - } - - const std::string& content() const { - return content_; - } - - int content_length() const { - return content_.size(); - } - - const std::string tool() const { - return GetHeaderWithEmptyDefault(DevToolsRemoteMessageHeaders::kTool); - } - - const std::string destination() const { - return GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kDestination); - } - - // Returns the header value providing default_value if the header is absent. - const std::string GetHeader(const std::string& header_name, - const std::string& default_value) const; - - // Returns the header value providing an empty string if the header is absent. - const std::string GetHeaderWithEmptyDefault( - const std::string& header_name) const; - - // Returns a string representation of the message useful for the transfer to - // the remote debugger. - const std::string ToString() const; - - private: - HeaderMap header_map_; - std::string content_; - // Cannot DISALLOW_COPY_AND_ASSIGN(DevToolsRemoteMessage) since it is passed - // as an IPC message argument and needs to be copied. -}; - -// Facilitates easy construction of outbound (Chrome -> remote debugger) -// DevToolsRemote messages. -class DevToolsRemoteMessageBuilder { - public: - // A singleton instance getter. - static DevToolsRemoteMessageBuilder& instance(); - // Creates a message given the certain header values and a payload. - DevToolsRemoteMessage* Create(const std::string& tool, - const std::string& destination, - const std::string& payload); - - private: - DevToolsRemoteMessageBuilder() {} - virtual ~DevToolsRemoteMessageBuilder() {} - DISALLOW_COPY_AND_ASSIGN(DevToolsRemoteMessageBuilder); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_MESSAGE_H_ diff --git a/content/browser/debugger/devtools_remote_message_unittest.cc b/content/browser/debugger/devtools_remote_message_unittest.cc deleted file mode 100644 index 0429e1a..0000000 --- a/content/browser/debugger/devtools_remote_message_unittest.cc +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -#include "base/memory/scoped_ptr.h" -#include "base/string_number_conversions.h" -#include "content/browser/debugger/devtools_remote.h" -#include "content/browser/debugger/devtools_remote_message.h" -#include "testing/gtest/include/gtest/gtest.h" - -class DevToolsRemoteMessageTest : public testing::Test { - public: - DevToolsRemoteMessageTest() : testing::Test() {} - - protected: - virtual void SetUp() { - testing::Test::SetUp(); - } -}; - -TEST_F(DevToolsRemoteMessageTest, ConstructInstanceManually) { - DevToolsRemoteMessage::HeaderMap headers; - std::string content = "{\"command\":\"ping\"}"; - headers[DevToolsRemoteMessageHeaders::kTool] = "DevToolsService"; - headers[DevToolsRemoteMessageHeaders::kContentLength] = - base::IntToString(content.size()); - - DevToolsRemoteMessage message(headers, content); - ASSERT_STREQ("DevToolsService", - message.GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kTool).c_str()); - ASSERT_STREQ("DevToolsService", message.tool().c_str()); - ASSERT_STREQ(content.c_str(), message.content().c_str()); - ASSERT_EQ(content.size(), - static_cast<std::string::size_type>(message.content_length())); - ASSERT_EQ(static_cast<DevToolsRemoteMessage::HeaderMap::size_type>(2), - message.headers().size()); -} - -TEST_F(DevToolsRemoteMessageTest, ConstructWithBuilder) { - std::string content = "Responsecontent"; - scoped_ptr<DevToolsRemoteMessage> message( - DevToolsRemoteMessageBuilder::instance().Create( - "V8Debugger", // tool - "2", // destination - content)); // content - - ASSERT_EQ(static_cast<DevToolsRemoteMessage::HeaderMap::size_type>(3), - message->headers().size()); - ASSERT_STREQ( - "V8Debugger", - message->GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kTool).c_str()); - ASSERT_STREQ( - "V8Debugger", - message->tool().c_str()); - ASSERT_STREQ( - "2", - message->GetHeaderWithEmptyDefault( - DevToolsRemoteMessageHeaders::kDestination).c_str()); - ASSERT_STREQ( - "2", - message->destination().c_str()); - ASSERT_EQ(content.size(), - static_cast<DevToolsRemoteMessage::HeaderMap::size_type>( - message->content_length())); - ASSERT_STREQ(content.c_str(), message->content().c_str()); -} diff --git a/content/browser/debugger/devtools_remote_service.cc b/content/browser/debugger/devtools_remote_service.cc deleted file mode 100644 index 296c183..0000000 --- a/content/browser/debugger/devtools_remote_service.cc +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/debugger/devtools_remote_service.h" - -#include <string> - -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/memory/scoped_ptr.h" -#include "base/values.h" -#include "chrome/browser/sessions/restore_tab_helper.h" -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "content/browser/debugger/devtools_manager.h" -#include "content/browser/debugger/devtools_protocol_handler.h" -#include "content/browser/debugger/devtools_remote_message.h" -#include "content/browser/debugger/inspectable_tab_proxy.h" -#include "content/browser/tab_contents/navigation_controller.h" -#include "content/browser/tab_contents/navigation_entry.h" -#include "content/common/devtools_messages.h" - -const char DevToolsRemoteServiceCommand::kPing[] = "ping"; -const char DevToolsRemoteServiceCommand::kVersion[] = "version"; -const char DevToolsRemoteServiceCommand::kListTabs[] = "list_tabs"; - -const char DevToolsRemoteService::kToolName[] = "DevToolsService"; - -namespace { -const char kCommandKey[] = "command"; -const char kDataKey[] = "data"; -const char kResultKey[] = "result"; -} // namespace - -DevToolsRemoteService::DevToolsRemoteService(DevToolsProtocolHandler* delegate) - : delegate_(delegate) {} - -DevToolsRemoteService::~DevToolsRemoteService() {} - -void DevToolsRemoteService::HandleMessage( - const DevToolsRemoteMessage& message) { - scoped_ptr<Value> request(base::JSONReader::Read(message.content(), false)); - if (request.get() == NULL) { - // Bad JSON - NOTREACHED(); - return; - } - DictionaryValue* json; - if (request->IsType(Value::TYPE_DICTIONARY)) { - json = static_cast<DictionaryValue*>(request.get()); - if (!json->HasKey(kCommandKey)) { - NOTREACHED(); // Broken protocol - no "command" specified - return; - } - } else { - NOTREACHED(); // Broken protocol - not a JS object - return; - } - ProcessJson(json, message); -} - -void DevToolsRemoteService::ProcessJson(DictionaryValue* json, - const DevToolsRemoteMessage& message) { - static const std::string kOkResponse = "ok"; // "Ping" response - static const std::string kVersion = "0.1"; // Current protocol version - std::string command; - DictionaryValue response; - - json->GetString(kCommandKey, &command); - response.SetString(kCommandKey, command); - - if (command == DevToolsRemoteServiceCommand::kPing) { - response.SetInteger(kResultKey, Result::kOk); - response.SetString(kDataKey, kOkResponse); - } else if (command == DevToolsRemoteServiceCommand::kVersion) { - response.SetInteger(kResultKey, Result::kOk); - response.SetString(kDataKey, kVersion); - } else if (command == DevToolsRemoteServiceCommand::kListTabs) { - ListValue* data = new ListValue(); - const InspectableTabProxy::TabMap& tab_map = - delegate_->inspectable_tab_proxy()->tab_map(); - for (InspectableTabProxy::TabMap::const_iterator it = - tab_map.begin(), end = tab_map.end(); it != end; ++it) { - NavigationEntry* entry = it->second->controller().GetActiveEntry(); - if (entry == NULL) { - continue; - } - if (entry->url().is_valid()) { - ListValue* tab = new ListValue(); - tab->Append(Value::CreateIntegerValue( - it->second->restore_tab_helper()->session_id().id())); - tab->Append(Value::CreateStringValue(entry->url().spec())); - data->Append(tab); - } - } - response.SetInteger(kResultKey, Result::kOk); - response.Set(kDataKey, data); - } else { - // Unknown protocol command. - NOTREACHED(); - response.SetInteger(kResultKey, Result::kUnknownCommand); - } - std::string response_json; - base::JSONWriter::Write(&response, false, &response_json); - scoped_ptr<DevToolsRemoteMessage> response_message( - DevToolsRemoteMessageBuilder::instance().Create(message.tool(), - message.destination(), - response_json)); - delegate_->Send(*response_message.get()); -} diff --git a/content/browser/debugger/devtools_remote_service.h b/content/browser/debugger/devtools_remote_service.h deleted file mode 100644 index 165e277..0000000 --- a/content/browser/debugger/devtools_remote_service.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_SERVICE_H_ -#define CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_SERVICE_H_ -#pragma once - -#include "base/basictypes.h" -#include "content/browser/debugger/devtools_remote.h" - -class DevToolsRemoteMessage; -class DevToolsProtocolHandler; - -namespace base { -class DictionaryValue; -} - -// Contains constants for DevToolsRemoteService tool protocol commands. -struct DevToolsRemoteServiceCommand { - static const char kPing[]; - static const char kVersion[]; - static const char kListTabs[]; -}; - -// Handles Chrome remote debugger protocol service commands. -class DevToolsRemoteService : public DevToolsRemoteListener { - public: - explicit DevToolsRemoteService(DevToolsProtocolHandler* delegate); - - // DevToolsRemoteListener interface - virtual void HandleMessage(const DevToolsRemoteMessage& message); - virtual void OnConnectionLost() {} - - static const char kToolName[]; - - private: - // Operation result returned in the "result" field. - struct Result { - static const int kOk = 0; - static const int kUnknownCommand = 1; - }; - virtual ~DevToolsRemoteService(); - void ProcessJson(base::DictionaryValue* json, - const DevToolsRemoteMessage& message); - DevToolsProtocolHandler* delegate_; - DISALLOW_COPY_AND_ASSIGN(DevToolsRemoteService); -}; - -#endif // CONTENT_BROWSER_DEBUGGER_DEVTOOLS_REMOTE_SERVICE_H_ diff --git a/content/browser/debugger/devtools_sanity_unittest.cc b/content/browser/debugger/devtools_sanity_unittest.cc deleted file mode 100644 index fad56b0..0000000 --- a/content/browser/debugger/devtools_sanity_unittest.cc +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/command_line.h" -#include "base/path_service.h" -#include "base/stringprintf.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/debugger/devtools_window.h" -#include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/common/chrome_notification_types.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/test/in_process_browser_test.h" -#include "chrome/test/ui_test_utils.h" -#include "content/browser/content_browser_client.h" -#include "content/browser/debugger/devtools_client_host.h" -#include "content/browser/debugger/devtools_manager.h" -#include "content/browser/debugger/worker_devtools_manager_io.h" -#include "content/browser/renderer_host/render_view_host.h" -#include "content/browser/tab_contents/tab_contents.h" -#include "content/browser/worker_host/worker_process_host.h" -#include "content/common/notification_registrar.h" -#include "content/common/notification_service.h" -#include "net/test/test_server.h" - -namespace { - -// Used to block until a dev tools client window's browser is closed. -class BrowserClosedObserver : public NotificationObserver { - public: - explicit BrowserClosedObserver(Browser* browser) { - registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED, - Source<Browser>(browser)); - ui_test_utils::RunMessageLoop(); - } - - virtual void Observe(int type, - const NotificationSource& source, - const NotificationDetails& details) { - MessageLoopForUI::current()->Quit(); - } - - private: - NotificationRegistrar registrar_; - DISALLOW_COPY_AND_ASSIGN(BrowserClosedObserver); -}; - -// The delay waited in some cases where we don't have a notifications for an -// action we take. -const int kActionDelayMs = 500; - -const char kDebuggerTestPage[] = "files/devtools/debugger_test_page.html"; -const char kPauseWhenLoadingDevTools[] = - "files/devtools/pause_when_loading_devtools.html"; -const char kPauseWhenScriptIsRunning[] = - "files/devtools/pause_when_script_is_running.html"; -const char kPageWithContentScript[] = - "files/devtools/page_with_content_script.html"; -const char kChunkedTestPage[] = "chunked"; -const char kSlowTestPage[] = - "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2"; -const char kSharedWorkerTestPage[] = - "files/workers/workers_ui_shared_worker.html"; - -void RunTestFuntion(DevToolsWindow* window, const char* test_name) { - std::string result; - - // At first check that JavaScript part of the front-end is loaded by - // checking that global variable uiTests exists(it's created after all js - // files have been loaded) and has runTest method. - ASSERT_TRUE( - ui_test_utils::ExecuteJavaScriptAndExtractString( - window->GetRenderViewHost(), - L"", - L"window.domAutomationController.send(" - L"'' + (window.uiTests && (typeof uiTests.runTest)));", - &result)); - - if (result == "function") { - ASSERT_TRUE( - ui_test_utils::ExecuteJavaScriptAndExtractString( - window->GetRenderViewHost(), - L"", - UTF8ToWide(base::StringPrintf("uiTests.runTest('%s')", - test_name)), - &result)); - EXPECT_EQ("[OK]", result); - } else { - FAIL() << "DevTools front-end is broken."; - } -} - -class DevToolsSanityTest : public InProcessBrowserTest { - public: - DevToolsSanityTest() - : window_(NULL), - inspected_rvh_(NULL) { - set_show_window(true); - EnableDOMAutomation(); - } - - protected: - void RunTest(const std::string& test_name, const std::string& test_page) { - OpenDevToolsWindow(test_page); - RunTestFuntion(window_, test_name.c_str()); - CloseDevToolsWindow(); - } - - void OpenDevToolsWindow(const std::string& test_page) { - ASSERT_TRUE(test_server()->Start()); - GURL url = test_server()->GetURL(test_page); - ui_test_utils::NavigateToURL(browser(), url); - - inspected_rvh_ = GetInspectedTab()->render_view_host(); - window_ = DevToolsWindow::OpenDevToolsWindow(inspected_rvh_); - RenderViewHost* client_rvh = window_->GetRenderViewHost(); - TabContents* client_contents = client_rvh->delegate()->GetAsTabContents(); - ui_test_utils::WaitForNavigation(&client_contents->controller()); - } - - TabContents* GetInspectedTab() { - return browser()->GetTabContentsAt(0); - } - - void CloseDevToolsWindow() { - DevToolsManager* devtools_manager = DevToolsManager::GetInstance(); - // UnregisterDevToolsClientHostFor may destroy window_ so store the browser - // first. - Browser* browser = window_->browser(); - devtools_manager->UnregisterDevToolsClientHostFor(inspected_rvh_); - - // Wait only when DevToolsWindow has a browser. For docked DevTools, this - // is NULL and we skip the wait. - if (browser) - BrowserClosedObserver close_observer(browser); - } - - DevToolsWindow* window_; - RenderViewHost* inspected_rvh_; -}; - - -class CancelableQuitTask : public Task { - public: - explicit CancelableQuitTask(const std::string& timeout_message) - : timeout_message_(timeout_message), - cancelled_(false) { - } - - void cancel() { - cancelled_ = true; - } - - virtual void Run() { - if (cancelled_) { - return; - } - FAIL() << timeout_message_; - MessageLoop::current()->Quit(); - } - - private: - std::string timeout_message_; - bool cancelled_; -}; - - -// Base class for DevTools tests that test devtools functionality for -// extensions and content scripts. -class DevToolsExtensionDebugTest : public DevToolsSanityTest, - public NotificationObserver { - public: - DevToolsExtensionDebugTest() : DevToolsSanityTest() { - PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_); - test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools"); - test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions"); - } - - protected: - // Load an extention from test\data\devtools\extensions\<extension_name> - void LoadExtension(const char* extension_name) { - FilePath path = test_extensions_dir_.AppendASCII(extension_name); - ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension."; - } - - private: - bool LoadExtensionFromPath(const FilePath& path) { - ExtensionService* service = browser()->profile()->GetExtensionService(); - size_t num_before = service->extensions()->size(); - { - NotificationRegistrar registrar; - registrar.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, - NotificationService::AllSources()); - CancelableQuitTask* delayed_quit = - new CancelableQuitTask("Extension load timed out."); - MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_quit, - 4*1000); - service->LoadExtension(path); - ui_test_utils::RunMessageLoop(); - delayed_quit->cancel(); - } - size_t num_after = service->extensions()->size(); - if (num_after != (num_before + 1)) - return false; - - return WaitForExtensionHostsToLoad(); - } - - bool WaitForExtensionHostsToLoad() { - // Wait for all the extension hosts that exist to finish loading. - // NOTE: This assumes that the extension host list is not changing while - // this method is running. - - NotificationRegistrar registrar; - registrar.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, - NotificationService::AllSources()); - CancelableQuitTask* delayed_quit = - new CancelableQuitTask("Extension host load timed out."); - MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_quit, - 4*1000); - - ExtensionProcessManager* manager = - browser()->profile()->GetExtensionProcessManager(); - for (ExtensionProcessManager::const_iterator iter = manager->begin(); - iter != manager->end();) { - if ((*iter)->did_stop_loading()) - ++iter; - else - ui_test_utils::RunMessageLoop(); - } - - delayed_quit->cancel(); - return true; - } - - void Observe(int type, - const NotificationSource& source, - const NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_EXTENSION_LOADED: - case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: - MessageLoopForUI::current()->Quit(); - break; - default: - NOTREACHED(); - break; - } - } - - FilePath test_extensions_dir_; -}; - - - -// Used to block until a navigation completes. -class LoadStopObserver : public NotificationObserver { - public: - explicit LoadStopObserver(const NotificationSource& source) : done_(false) { - registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, source); - ui_test_utils::RunMessageLoop(); - } - - private: - virtual void Observe(int type, - const NotificationSource& source, - const NotificationDetails& details) { - if (type == content::NOTIFICATION_LOAD_STOP) { - if (done_) - return; - done_ = true; - MessageLoopForUI::current()->Quit(); - } - } - - NotificationRegistrar registrar_; - bool done_; - DISALLOW_COPY_AND_ASSIGN(LoadStopObserver); -}; - - -class WorkerDevToolsSanityTest : public InProcessBrowserTest { - public: - WorkerDevToolsSanityTest() : window_(NULL) { - set_show_window(true); - EnableDOMAutomation(); - } - - protected: - void RunTest(const char* test_name, const char* test_page) { - ASSERT_TRUE(test_server()->Start()); - GURL url = test_server()->GetURL(test_page); - ui_test_utils::NavigateToURL(browser(), url); - - OpenDevToolsWindowForFirstSharedWorker(); - RunTestFuntion(window_, test_name); - CloseDevToolsWindow(); - } - - static void OpenDevToolsWindowForFirstSharedWorkerOnIOThread(int attempt) { - BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); - bool found = false; - for (; !iter.Done(); ++iter) { - WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - const WorkerProcessHost::Instances& instances = worker->instances(); - for (WorkerProcessHost::Instances::const_iterator i = instances.begin(); - i != instances.end(); ++i) { - if (!i->shared()) - continue; - WorkerDevToolsManagerIO::GetInstance()->OpenDevToolsForWorker( - worker->id(), i->worker_route_id()); - found = true; - break; - } - } - if (found) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - new MessageLoop::QuitTask); - } else if(attempt < 30) { - MessageLoop::current()->PostDelayedTask( - FROM_HERE, - NewRunnableFunction( - &OpenDevToolsWindowForFirstSharedWorkerOnIOThread, attempt + 1), - 100); - } else { - FAIL() << "Shared worker not found."; - } - - } - - void OpenDevToolsWindowForFirstSharedWorker() { - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableFunction( - &OpenDevToolsWindowForFirstSharedWorkerOnIOThread, 1)); - ui_test_utils::RunMessageLoop(); - window_ = static_cast<DevToolsWindow*>( - DevToolsClientHost::GetDevToolsClientHostForTest()); - ASSERT_TRUE(window_ != NULL); - - RenderViewHost* client_rvh = window_->GetRenderViewHost(); - TabContents* client_contents = client_rvh->delegate()->GetAsTabContents(); - if (client_contents->is_loading()) { - LoadStopObserver( - Source<NavigationController>(&client_contents->controller())); - } - } - - void CloseDevToolsWindow() { - Browser* browser = window_->browser(); - browser->CloseAllTabs(); - BrowserClosedObserver close_observer(browser); - } - - DevToolsWindow* window_; -}; - - -// Tests scripts panel showing. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestShowScriptsTab) { - RunTest("testShowScriptsTab", kDebuggerTestPage); -} - -// Tests that scripts tab is populated with inspected scripts even if it -// hadn't been shown by the moment inspected paged refreshed. -// @see http://crbug.com/26312 -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, - TestScriptsTabIsPopulatedOnInspectedPageRefresh) { - // Clear inspector settings to ensure that Elements will be - // current panel when DevTools window is open. - content::GetContentClient()->browser()->ClearInspectorSettings( - GetInspectedTab()->render_view_host()); - RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh", - kDebuggerTestPage); -} - -// Tests that a content script is in the scripts list. -// This test is disabled, see bug 28961. -IN_PROC_BROWSER_TEST_F(DevToolsExtensionDebugTest, - TestContentScriptIsPresent) { - LoadExtension("simple_content_script"); - RunTest("testContentScriptIsPresent", kPageWithContentScript); -} - -// Tests that scripts are not duplicated after Scripts Panel switch. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, - TestNoScriptDuplicatesOnPanelSwitch) { - RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage); -} - -// Tests that debugger works correctly if pause event occurs when DevTools -// frontend is being loaded. -// Flaky - http://crbug.com/69719. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, FLAKY_TestPauseWhenLoadingDevTools) { - RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools); -} - -// Tests that pressing 'Pause' will pause script execution if the script -// is already running. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, FLAKY_TestPauseWhenScriptIsRunning) { - RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning); -} - -// Tests network timing. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) { - RunTest("testNetworkTiming", kSlowTestPage); -} - -// Tests network size. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) { - RunTest("testNetworkSize", kChunkedTestPage); -} - -// Tests raw headers text. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) { - RunTest("testNetworkSyncSize", kChunkedTestPage); -} - -// Tests raw headers text. -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) { - RunTest("testNetworkRawHeadersText", kChunkedTestPage); -} - -IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) { - OpenDevToolsWindow("about:blank"); - std::string result; - ASSERT_TRUE( - ui_test_utils::ExecuteJavaScriptAndExtractString( - window_->GetRenderViewHost(), - L"", - L"window.domAutomationController.send(" - L"'' + (window.uiTests && (typeof uiTests.runTest)));", - &result)); - ASSERT_EQ("function", result) << "DevTools front-end is broken."; - CloseDevToolsWindow(); -} - -// http://crbug.com/89845 -IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, DISABLED_InspectSharedWorker) { - RunTest("testSharedWorker", kSharedWorkerTestPage); -} - -} // namespace diff --git a/content/browser/debugger/extension_ports_remote_service.cc b/content/browser/debugger/extension_ports_remote_service.cc deleted file mode 100644 index 14e840a..0000000 --- a/content/browser/debugger/extension_ports_remote_service.cc +++ /dev/null @@ -1,385 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Implementation of the ExtensionPortsRemoteService. - -// Inspired significantly from debugger_remote_service -// and ../automation/extension_port_container. - -#include "content/browser/debugger/extension_ports_remote_service.h" - -#include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/message_loop.h" -#include "base/string_number_conversions.h" -#include "base/values.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "chrome/common/extensions/extension_messages.h" -#include "content/browser/debugger/devtools_manager.h" -#include "content/browser/debugger/devtools_protocol_handler.h" -#include "content/browser/debugger/devtools_remote_message.h" -#include "content/browser/debugger/inspectable_tab_proxy.h" -#include "content/browser/tab_contents/tab_contents.h" -#include "content/common/devtools_messages.h" - -namespace { - -// Protocol is as follows: -// -// From external client: -// {"command": "connect", -// "data": { -// "extensionId": "<extension_id string>", -// "channelName": "<port name string>", (optional) -// "tabId": <numerical tab ID> (optional) -// } -// } -// To connect to a background page or tool strip, the tabId should be omitted. -// Tab IDs can be enumerated with the list_tabs DevToolsService command. -// -// Response: -// {"command": "connect", -// "result": 0, (assuming success) -// "data": { -// "portId": <numerical port ID> -// } -// } -// -// Posting a message from external client: -// Put the target message port ID in the devtools destination field. -// {"command": "postMessage", -// "data": <message body - arbitrary JSON> -// } -// Response: -// {"command": "postMessage", -// "result": 0 (Assuming success) -// } -// Note this is a confirmation from the devtools protocol layer, not -// a response from the extension. -// -// Message from an extension to the external client: -// The message port ID is in the devtools destination field. -// {"command": "onMessage", -// "result": 0, (Always 0) -// "data": <message body - arbitrary JSON> -// } -// -// The "disconnect" command from the external client, and -// "onDisconnect" notification from the ExtensionMessageService, are -// similar: with the message port ID in the destination field, but no -// "data" field in this case. - -// Commands: -const char kConnect[] = "connect"; -const char kDisconnect[] = "disconnect"; -const char kPostMessage[] = "postMessage"; -// Events: -const char kOnMessage[] = "onMessage"; -const char kOnDisconnect[] = "onDisconnect"; - -// Constants for the JSON message fields. -// The type is wstring because the constant is used to get a -// DictionaryValue field (which requires a wide string). - -// Mandatory. -const char kCommandKey[] = "command"; - -// Always present in messages sent to the external client. -const char kResultKey[] = "result"; - -// Field for command-specific parameters. Not strictly necessary, but -// makes it more similar to the remote debugger protocol, which should -// allow easier reuse of client code. -const char kDataKey[] = "data"; - -// Fields within the "data" dictionary: - -// Required for "connect": -const char kExtensionIdKey[] = "extensionId"; -// Optional in "connect": -const char kChannelNameKey[] = "channelName"; -const char kTabIdKey[] = "tabId"; - -// Present under "data" in replies to a successful "connect" . -const char kPortIdKey[] = "portId"; - -} // namespace - -const std::string ExtensionPortsRemoteService::kToolName = "ExtensionPorts"; - -ExtensionPortsRemoteService::ExtensionPortsRemoteService( - DevToolsProtocolHandler* delegate) - : delegate_(delegate), service_(NULL) { - // We need an ExtensionMessageService instance. It hangs off of - // |profile|. But we do not have a particular tab or RenderViewHost - // as context. I'll just use the first active profile not in - // incognito mode. But this is probably not the right way. - ProfileManager* profile_manager = g_browser_process->profile_manager(); - if (!profile_manager) { - LOG(WARNING) << "No profile manager for ExtensionPortsRemoteService"; - return; - } - - std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles()); - for (size_t i = 0; i < profiles.size(); ++i) { - if (!profiles[i]->IsOffTheRecord()) { - service_ = profiles[i]->GetExtensionMessageService(); - break; - } - } - if (!service_) - LOG(WARNING) << "No usable profile for ExtensionPortsRemoteService"; -} - -ExtensionPortsRemoteService::~ExtensionPortsRemoteService() { -} - -void ExtensionPortsRemoteService::HandleMessage( - const DevToolsRemoteMessage& message) { - DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); - const std::string destinationString = message.destination(); - scoped_ptr<Value> request(base::JSONReader::Read(message.content(), true)); - if (request.get() == NULL) { - // Bad JSON - NOTREACHED(); - return; - } - DictionaryValue* content; - if (!request->IsType(Value::TYPE_DICTIONARY)) { - NOTREACHED(); // Broken protocol :( - return; - } - content = static_cast<DictionaryValue*>(request.get()); - if (!content->HasKey(kCommandKey)) { - NOTREACHED(); // Broken protocol :( - return; - } - std::string command; - DictionaryValue response; - - content->GetString(kCommandKey, &command); - response.SetString(kCommandKey, command); - - if (!service_) { - // This happens if we failed to obtain an ExtensionMessageService - // during initialization. - NOTREACHED(); - response.SetInteger(kResultKey, RESULT_NO_SERVICE); - SendResponse(response, message.tool(), message.destination()); - return; - } - - int destination = -1; - if (!destinationString.empty()) - base::StringToInt(destinationString, &destination); - - if (command == kConnect) { - if (destination != -1) // destination should be empty for this command. - response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); - else - ConnectCommand(content, &response); - } else if (command == kDisconnect) { - if (destination == -1) // Destination required for this command. - response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); - else - DisconnectCommand(destination, &response); - } else if (command == kPostMessage) { - if (destination == -1) // Destination required for this command. - response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); - else - PostMessageCommand(destination, content, &response); - } else { - // Unknown command - NOTREACHED(); - response.SetInteger(kResultKey, RESULT_UNKNOWN_COMMAND); - } - SendResponse(response, message.tool(), message.destination()); -} - -void ExtensionPortsRemoteService::OnConnectionLost() { - VLOG(1) << "OnConnectionLost"; - DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); - DCHECK(service_); - for (PortIdSet::iterator it = openPortIds_.begin(); - it != openPortIds_.end(); - ++it) - service_->CloseChannel(*it); - openPortIds_.clear(); -} - -void ExtensionPortsRemoteService::SendResponse( - const Value& response, const std::string& tool, - const std::string& destination) { - std::string response_content; - base::JSONWriter::Write(&response, false, &response_content); - scoped_ptr<DevToolsRemoteMessage> response_message( - DevToolsRemoteMessageBuilder::instance().Create( - tool, destination, response_content)); - delegate_->Send(*response_message.get()); -} - -bool ExtensionPortsRemoteService::Send(IPC::Message *message) { - DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); - - IPC_BEGIN_MESSAGE_MAP(ExtensionPortsRemoteService, *message) - IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke) - IPC_MESSAGE_UNHANDLED_ERROR() - IPC_END_MESSAGE_MAP() - - delete message; - return true; -} - -void ExtensionPortsRemoteService::OnExtensionMessageInvoke( - const std::string& extension_id, - const std::string& function_name, - const ListValue& args, - const GURL& event_url) { - if (function_name == ExtensionMessageService::kDispatchOnMessage) { - DCHECK_EQ(args.GetSize(), 2u); - std::string message; - int port_id; - if (args.GetString(0, &message) && args.GetInteger(1, &port_id)) - OnExtensionMessage(message, port_id); - } else if (function_name == ExtensionMessageService::kDispatchOnDisconnect) { - DCHECK_EQ(args.GetSize(), 1u); - int port_id; - if (args.GetInteger(0, &port_id)) - OnExtensionPortDisconnected(port_id); - } else if (function_name == ExtensionMessageService::kDispatchOnConnect) { - // There is no way for this service to be addressed and receive - // connections. - NOTREACHED() << function_name << " shouldn't be called."; - } else { - NOTREACHED() << function_name << " shouldn't be called."; - } -} - -void ExtensionPortsRemoteService::OnExtensionMessage( - const std::string& message, int port_id) { - VLOG(1) << "Message event: from port " << port_id << ", < " << message << ">"; - // Transpose the information into a JSON message for the external client. - DictionaryValue content; - content.SetString(kCommandKey, kOnMessage); - content.SetInteger(kResultKey, RESULT_OK); - // Turn the stringified message body back into JSON. - Value* data = base::JSONReader::Read(message, false); - if (!data) { - NOTREACHED(); - return; - } - content.Set(kDataKey, data); - SendResponse(content, kToolName, base::IntToString(port_id)); -} - -void ExtensionPortsRemoteService::OnExtensionPortDisconnected(int port_id) { - VLOG(1) << "Disconnect event for port " << port_id; - openPortIds_.erase(port_id); - DictionaryValue content; - content.SetString(kCommandKey, kOnDisconnect); - content.SetInteger(kResultKey, RESULT_OK); - SendResponse(content, kToolName, base::IntToString(port_id)); -} - -void ExtensionPortsRemoteService::ConnectCommand( - DictionaryValue* content, DictionaryValue* response) { - // Parse out the parameters. - DictionaryValue* data; - if (!content->GetDictionary(kDataKey, &data)) { - response->SetInteger(kResultKey, RESULT_PARAMETER_ERROR); - return; - } - std::string extension_id; - if (!data->GetString(kExtensionIdKey, &extension_id)) { - response->SetInteger(kResultKey, RESULT_PARAMETER_ERROR); - return; - } - std::string channel_name = ""; - data->GetString(kChannelNameKey, &channel_name); // optional. - int tab_id = -1; - data->GetInteger(kTabIdKey, &tab_id); // optional. - int port_id; - if (tab_id != -1) { // Resolve the tab ID. - const InspectableTabProxy::TabMap& tab_map = - delegate_->inspectable_tab_proxy()->tab_map(); - InspectableTabProxy::TabMap::const_iterator it = tab_map.find(tab_id); - TabContents* tab_contents = NULL; - if (it != tab_map.end()) - tab_contents = it->second->tab_contents(); - if (!tab_contents) { - VLOG(1) << "tab not found: " << tab_id; - response->SetInteger(kResultKey, RESULT_TAB_NOT_FOUND); - return; - } - // Ask the ExtensionMessageService to open the channel. - VLOG(1) << "Connect: extension_id <" << extension_id - << ">, channel_name <" << channel_name - << ">, tab " << tab_id; - DCHECK(service_); - port_id = service_->OpenSpecialChannelToTab( - extension_id, channel_name, tab_contents, this); - } else { // no tab: channel to an extension' background page / toolstrip. - // Ask the ExtensionMessageService to open the channel. - VLOG(1) << "Connect: extension_id <" << extension_id - << ">, channel_name <" << channel_name << ">"; - DCHECK(service_); - port_id = service_->OpenSpecialChannelToExtension( - extension_id, channel_name, "null", this); - } - if (port_id == -1) { - // Failure: probably the extension ID doesn't exist. - VLOG(1) << "Connect failed"; - response->SetInteger(kResultKey, RESULT_CONNECT_FAILED); - return; - } - VLOG(1) << "Connected: port " << port_id; - openPortIds_.insert(port_id); - // Reply to external client with the port ID assigned to the new channel. - DictionaryValue* reply_data = new DictionaryValue(); - reply_data->SetInteger(kPortIdKey, port_id); - response->Set(kDataKey, reply_data); - response->SetInteger(kResultKey, RESULT_OK); -} - -void ExtensionPortsRemoteService::DisconnectCommand( - int port_id, DictionaryValue* response) { - VLOG(1) << "Disconnect port " << port_id; - PortIdSet::iterator portEntry = openPortIds_.find(port_id); - if (portEntry == openPortIds_.end()) { // unknown port ID. - VLOG(1) << "unknown port: " << port_id; - response->SetInteger(kResultKey, RESULT_UNKNOWN_PORT); - return; - } - DCHECK(service_); - service_->CloseChannel(port_id); - openPortIds_.erase(portEntry); - response->SetInteger(kResultKey, RESULT_OK); -} - -void ExtensionPortsRemoteService::PostMessageCommand( - int port_id, DictionaryValue* content, DictionaryValue* response) { - Value* data; - if (!content->Get(kDataKey, &data)) { - response->SetInteger(kResultKey, RESULT_PARAMETER_ERROR); - return; - } - std::string message; - // Stringified the JSON message body. - base::JSONWriter::Write(data, false, &message); - VLOG(1) << "postMessage: port " << port_id - << ", message: <" << message << ">"; - PortIdSet::iterator portEntry = openPortIds_.find(port_id); - if (portEntry == openPortIds_.end()) { // Unknown port ID. - VLOG(1) << "unknown port: " << port_id; - response->SetInteger(kResultKey, RESULT_UNKNOWN_PORT); - return; - } - // Post the message through the ExtensionMessageService. - DCHECK(service_); - service_->PostMessageFromRenderer(port_id, message); - // Confirm to the external client that we sent its message. - response->SetInteger(kResultKey, RESULT_OK); -} diff --git a/content/browser/debugger/extension_ports_remote_service.h b/content/browser/debugger/extension_ports_remote_service.h deleted file mode 100644 index eb96ddeb..0000000 --- a/content/browser/debugger/extension_ports_remote_service.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// ExtensionsPorts service: wires extension message ports through the -// devtools remote protocol, allowing an external client program to -// exchange messages with Chrome extensions. - -#ifndef CHROME_BROWSER_DEBUGGER_EXTENSION_PORTS_REMOTE_SERVICE_H_ -#define CHROME_BROWSER_DEBUGGER_EXTENSION_PORTS_REMOTE_SERVICE_H_ -#pragma once - -#include <set> -#include <string> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "chrome/browser/extensions/extension_message_service.h" -#include "content/browser/debugger/devtools_remote.h" -#include "ipc/ipc_message.h" - -class DevToolsProtocolHandler; -class DevToolsRemoteMessage; -class GURL; - -namespace base { -class DictionaryValue; -class ListValue; -class Value; -} - -class ExtensionPortsRemoteService : public DevToolsRemoteListener, - public IPC::Message::Sender { - public: - // Specifies a tool name ("ExtensionPorts") handled by this class. - static const std::string kToolName; - - // |delegate| (never NULL) is the protocol handler instance which - // dispatches messages to this service. - // The ownership of |delegate| is NOT transferred to this class. - explicit ExtensionPortsRemoteService(DevToolsProtocolHandler* delegate); - - // DevToolsRemoteListener methods: - - // Processes |message| from the external client (where the tool is - // "ExtensionPorts"). - virtual void HandleMessage(const DevToolsRemoteMessage& message); - - // Gets invoked on the external client socket connection loss. - // Closes open message ports. - virtual void OnConnectionLost(); - - // IPC::Message::Sender methods: - - // This is the callback through which the ExtensionMessageService - // passes us messages from extensions as well as disconnect events. - virtual bool Send(IPC::Message* msg); - - private: - // Operation result returned in the "result" field in messages sent - // to the external client. - typedef enum { - RESULT_OK = 0, - RESULT_UNKNOWN_COMMAND, - RESULT_NO_SERVICE, - RESULT_PARAMETER_ERROR, - RESULT_UNKNOWN_PORT, - RESULT_TAB_NOT_FOUND, - RESULT_CONNECT_FAILED, // probably extension ID not found. - } Result; - - virtual ~ExtensionPortsRemoteService(); - - // Sends a JSON message with the |response| to the external client. - // |tool| and |destination| are used as the respective header values. - void SendResponse(const base::Value& response, - const std::string& tool, - const std::string& destination); - - // Handles a message from the ExtensionMessageService. - void OnExtensionMessageInvoke(const std::string& extension_id, - const std::string& function_name, - const base::ListValue& args, - const GURL& event_url); - // Handles a message sent from an extension through the - // ExtensionMessageService, to be passed to the external client. - void OnExtensionMessage(const std::string& message, int port_id); - // Handles a disconnect event sent from the ExtensionMessageService. - void OnExtensionPortDisconnected(int port_id); - - // Implementation for the commands we can receive from the external client. - // Opens a channel to an extension. - void ConnectCommand(base::DictionaryValue* content, - base::DictionaryValue* response); - // Disconnects a message port. - void DisconnectCommand(int port_id, base::DictionaryValue* response); - // Sends a message to an extension through an established message port. - void PostMessageCommand(int port_id, - base::DictionaryValue* content, - base::DictionaryValue* response); - - // The delegate is used to send responses and events back to the - // external client, and to resolve tab IDs. - DevToolsProtocolHandler* delegate_; - - // Set of message port IDs we successfully opened. - typedef std::set<int> PortIdSet; - PortIdSet openPortIds_; - - scoped_refptr<ExtensionMessageService> service_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionPortsRemoteService); -}; - -#endif // CHROME_BROWSER_DEBUGGER_EXTENSION_PORTS_REMOTE_SERVICE_H_ diff --git a/content/browser/debugger/inspectable_tab_proxy.cc b/content/browser/debugger/inspectable_tab_proxy.cc deleted file mode 100644 index 66511d8..0000000 --- a/content/browser/debugger/inspectable_tab_proxy.cc +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/debugger/inspectable_tab_proxy.h" - -#include "base/string_number_conversions.h" -#include "base/string_util.h" -#include "chrome/browser/sessions/restore_tab_helper.h" -#include "chrome/browser/sessions/session_id.h" -#include "chrome/browser/tabs/tab_strip_model.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" -#include "content/browser/debugger/debugger_remote_service.h" -#include "content/browser/debugger/devtools_client_host.h" -#include "content/browser/tab_contents/tab_contents.h" -#include "content/common/devtools_messages.h" - -DevToolsClientHostImpl::DevToolsClientHostImpl( - int32 id, - DebuggerRemoteService* service, - InspectableTabProxy::IdToClientHostMap* map) - : id_(id), - service_(service), - map_(map) {} - -DevToolsClientHostImpl::~DevToolsClientHostImpl() { - map_->erase(this->id_); -} - -// The debugged tab has closed. -void DevToolsClientHostImpl::InspectedTabClosing() { - TabClosed(); - delete this; -} - -// The remote debugger has detached. -void DevToolsClientHostImpl::CloseImpl() { - NotifyCloseListener(); - delete this; -} - -void DevToolsClientHostImpl::SendMessageToClient( - const IPC::Message& msg) { - // TODO(prybin): Restore FrameNavigate. - IPC_BEGIN_MESSAGE_MAP(DevToolsClientHostImpl, msg) - IPC_MESSAGE_HANDLER(DevToolsClientMsg_DebuggerOutput, OnDebuggerOutput); - IPC_MESSAGE_UNHANDLED_ERROR() - IPC_END_MESSAGE_MAP() -} - -void DevToolsClientHostImpl::TabReplaced(TabContents* new_tab) { - map_->erase(id_); - TabContentsWrapper* new_tab_wrapper = - TabContentsWrapper::GetCurrentWrapperForContents(new_tab); - DCHECK(new_tab_wrapper); - if (!new_tab_wrapper) - return; - id_ = new_tab_wrapper->restore_tab_helper()->session_id().id(); - (*map_)[id_] = this; -} - -void DevToolsClientHostImpl::OnDebuggerOutput(const std::string& data) { - service_->DebuggerOutput(id_, data); -} - -void DevToolsClientHostImpl::FrameNavigating(const std::string& url) { - service_->FrameNavigate(id_, url); -} - -void DevToolsClientHostImpl::TabClosed() { - service_->TabClosed(id_); -} - -InspectableTabProxy::InspectableTabProxy() {} - -InspectableTabProxy::~InspectableTabProxy() {} - -const InspectableTabProxy::TabMap& InspectableTabProxy::tab_map() { - tab_map_.clear(); - for (BrowserList::const_iterator it = BrowserList::begin(), - end = BrowserList::end(); it != end; ++it) { - TabStripModel* model = (*it)->tabstrip_model(); - for (int i = 0, size = model->count(); i < size; ++i) { - TabContentsWrapper* tab = model->GetTabContentsAt(i); - tab_map_[tab->restore_tab_helper()->session_id().id()] = tab; - } - } - return tab_map_; -} - -DevToolsClientHostImpl* InspectableTabProxy::ClientHostForTabId( - int32 id) { - InspectableTabProxy::IdToClientHostMap::const_iterator it = - id_to_client_host_map_.find(id); - if (it == id_to_client_host_map_.end()) { - return NULL; - } - return it->second; -} - -DevToolsClientHost* InspectableTabProxy::NewClientHost( - int32 id, - DebuggerRemoteService* service) { - DevToolsClientHostImpl* client_host = - new DevToolsClientHostImpl(id, service, &id_to_client_host_map_); - id_to_client_host_map_[id] = client_host; - return client_host; -} - -void InspectableTabProxy::OnRemoteDebuggerDetached() { - while (!id_to_client_host_map_.empty()) { - IdToClientHostMap::iterator it = id_to_client_host_map_.begin(); - it->second->debugger_remote_service()->DetachFromTab( - base::IntToString(it->first), NULL); - } -} diff --git a/content/browser/debugger/inspectable_tab_proxy.h b/content/browser/debugger/inspectable_tab_proxy.h deleted file mode 100644 index 0ccaf76..0000000 --- a/content/browser/debugger/inspectable_tab_proxy.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_DEBUGGER_INSPECTABLE_TAB_PROXY_H_ -#define CHROME_BROWSER_DEBUGGER_INSPECTABLE_TAB_PROXY_H_ -#pragma once - -#include <string> - -#include "base/basictypes.h" -#include "base/hash_tables.h" -#include "content/browser/debugger/devtools_client_host.h" - -class DebuggerRemoteService; -class DevToolsClientHost; -class DevToolsClientHostImpl; -struct DevToolsMessageData; -class TabContentsWrapper; - -// Proxies debugged tabs' TabContentsWrapper using their UIDs. -// Keeps track of tabs being debugged so that we can detach from -// them on remote debugger connection loss. -class InspectableTabProxy { - public: - typedef base::hash_map<int32, TabContentsWrapper*> TabMap; - typedef base::hash_map<int32, DevToolsClientHostImpl*> IdToClientHostMap; - - InspectableTabProxy(); - virtual ~InspectableTabProxy(); - - // Returns a map of SessionID to TabContentsWrapper for all Browser - // instances. Clients should not keep the result around for extended periods - // of time as tabs might get closed thus invalidating the map. - const TabMap& tab_map(); - - // Returns a DevToolsClientHostImpl for the given tab |id|. - DevToolsClientHostImpl* ClientHostForTabId(int32 id); - - // Creates a new DevToolsClientHost implementor instance. - // |id| is the UID of the tab to debug. - // |service| is the DebuggerRemoteService instance the DevToolsClient - // messages shall be dispatched to. - DevToolsClientHost* NewClientHost(int32 id, - DebuggerRemoteService* service); - - // Gets invoked when a remote debugger is detached. In this case we should - // send the corresponding message to the V8 debugger for each of the tabs - // the debugger is attached to, and invoke InspectedTabClosing(). - void OnRemoteDebuggerDetached(); - - private: - TabMap tab_map_; - IdToClientHostMap id_to_client_host_map_; - DISALLOW_COPY_AND_ASSIGN(InspectableTabProxy); -}; - - -// An internal implementation of DevToolsClientHost that delegates -// messages sent for DevToolsClient to a DebuggerShell instance. -class DevToolsClientHostImpl : public DevToolsClientHost { - public: - DevToolsClientHostImpl( - int32 id, - DebuggerRemoteService* service, - InspectableTabProxy::IdToClientHostMap* map); - virtual ~DevToolsClientHostImpl(); - - DebuggerRemoteService* debugger_remote_service() { - return service_; - } - - void CloseImpl(); - - // DevToolsClientHost interface - virtual void InspectedTabClosing(); - virtual void SendMessageToClient(const IPC::Message& msg); - virtual void TabReplaced(TabContents* new_tab); - - private: - // Message handling routines - void OnDebuggerOutput(const std::string& msg); - virtual void FrameNavigating(const std::string& url); - void TabClosed(); - - int32 id_; - DebuggerRemoteService* service_; - InspectableTabProxy::IdToClientHostMap* map_; -}; - -#endif // CHROME_BROWSER_DEBUGGER_INSPECTABLE_TAB_PROXY_H_ |