summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-12 08:47:54 +0000
committerkaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-12 08:47:54 +0000
commitead05635816265f14f92243baa56f40d4a31c01e (patch)
treef7ec7ca43de2cd36a26b4547816acf6a7580a274
parent3e5a076165f61312818e92ab712ade50e210c696 (diff)
downloadchromium_src-ead05635816265f14f92243baa56f40d4a31c01e.zip
chromium_src-ead05635816265f14f92243baa56f40d4a31c01e.tar.gz
chromium_src-ead05635816265f14f92243baa56f40d4a31c01e.tar.bz2
This is required to simplify the implementation of chrome.debugger.getTargets.
BUG=179342 Review URL: https://codereview.chromium.org/12319114 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187540 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/devtools/devtools_sanity_browsertest.cc74
-rw-r--r--chrome/browser/extensions/extension_service.cc4
-rw-r--r--chrome/browser/extensions/extension_service.h2
-rw-r--r--chrome/test/data/devtools/target_list/background.js62
-rw-r--r--chrome/test/data/devtools/target_list/manifest.json11
-rw-r--r--chrome/test/data/devtools/target_list/test_page.html6
-rw-r--r--content/browser/devtools/devtools_agent_host_impl.cc7
-rw-r--r--content/browser/devtools/devtools_agent_host_impl.h6
-rw-r--r--content/browser/devtools/devtools_http_handler_impl.cc184
-rw-r--r--content/browser/devtools/devtools_http_handler_impl.h14
-rw-r--r--content/browser/devtools/render_view_devtools_agent_host.cc46
-rw-r--r--content/public/browser/devtools_agent_host.h17
12 files changed, 282 insertions, 151 deletions
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc
index 67a61c2..40d03eb 100644
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -11,7 +11,9 @@
#include "base/stringprintf.h"
#include "base/test/test_timeouts.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/devtools/browser_list_tabcontents_provider.h"
#include "chrome/browser/devtools/devtools_window.h"
+#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/unpacked_installer.h"
@@ -29,6 +31,7 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_client_host.h"
+#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/devtools_manager.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
@@ -37,6 +40,7 @@
#include "content/public/browser/worker_service.h"
#include "content/public/browser/worker_service_observer.h"
#include "content/public/test/browser_test_utils.h"
+#include "net/base/tcp_listen_socket.h"
#include "net/test/test_server.h"
using content::BrowserThread;
@@ -610,4 +614,74 @@ IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestAddMessageToConsole) {
CloseDevToolsWindow();
}
+class RemoteDebuggingTest : public ExtensionBrowserTest {
+
+ class ResultCatcher : public content::NotificationObserver {
+ public:
+ ResultCatcher()
+ : notification_(chrome::NOTIFICATION_CHROME_END) {
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_PASSED,
+ content::NotificationService::AllSources());
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_TEST_FAILED,
+ content::NotificationService::AllSources());
+ }
+
+ virtual ~ResultCatcher() {
+ }
+
+ // Pumps the UI loop until a notification is received that an API test
+ // succeeded or failed. Returns true if the test succeeded, false otherwise.
+ bool GetNextResult() {
+ if (!received())
+ content::RunMessageLoop();
+
+ if (!received())
+ NOTREACHED();
+
+ return notification_ == chrome::NOTIFICATION_EXTENSION_TEST_PASSED;
+ }
+
+ private:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE {
+ if (received())
+ return;
+ notification_ = static_cast<chrome::NotificationType>(type);
+ MessageLoopForUI::current()->Quit();
+ }
+
+ content::NotificationRegistrar registrar_;
+
+ chrome::NotificationType notification_;
+
+ bool received() { return notification_ != chrome::NOTIFICATION_CHROME_END; }
+ };
+
+ protected:
+
+ bool RunExtensionTest(const std::string& directory) {
+ content::DevToolsHttpHandler* devtools_http_handler_ =
+ content::DevToolsHttpHandler::Start(
+ new net::TCPListenSocketFactory("127.0.0.1", 9222),
+ "",
+ new BrowserListTabContentsProvider(
+ profile(), chrome::HOST_DESKTOP_TYPE_NATIVE));
+
+ base::FilePath test_data_path;
+ PathService::Get(chrome::DIR_TEST_DATA, &test_data_path);
+ LoadExtension(
+ test_data_path.AppendASCII("devtools").AppendASCII(directory));
+
+ ResultCatcher catcher;
+ bool result = catcher.GetNextResult();
+ devtools_http_handler_->Stop();
+ return result;
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(RemoteDebuggingTest, TargetList) {
+ ASSERT_TRUE(RunExtensionTest("target_list"));
+}
+
} // namespace
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index ebe016b..a041040 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -728,9 +728,9 @@ void ExtensionService::ReloadExtensionWithEvents(
manager->GetBackgroundHostForExtension(extension_id);
if (host && DevToolsAgentHost::HasFor(host->render_view_host())) {
// Look for an open inspector for the background page.
- int devtools_cookie = DevToolsAgentHost::DisconnectRenderViewHost(
+ std::string devtools_cookie = DevToolsAgentHost::DisconnectRenderViewHost(
host->render_view_host());
- if (devtools_cookie >= 0)
+ if (devtools_cookie != std::string())
orphaned_dev_tools_[extension_id] = devtools_cookie;
}
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 0ddd9c8..f12d92b 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -912,7 +912,7 @@ class ExtensionService
// Map of inspector cookies that are detached, waiting for an extension to be
// reloaded.
- typedef std::map<std::string, int> OrphanedDevTools;
+ typedef std::map<std::string, std::string> OrphanedDevTools;
OrphanedDevTools orphaned_dev_tools_;
// Maps extension ids to a bitmask that indicates which events should be
diff --git a/chrome/test/data/devtools/target_list/background.js b/chrome/test/data/devtools/target_list/background.js
new file mode 100644
index 0000000..4fb3d92
--- /dev/null
+++ b/chrome/test/data/devtools/target_list/background.js
@@ -0,0 +1,62 @@
+// Copyright (c) 2013 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.
+
+function requestUrl(url, callback) {
+ var req = new XMLHttpRequest();
+ req.open('GET', url, true);
+ req.onload = function() {
+ if (req.status == 200)
+ callback(req.responseText);
+ else
+ req.onerror();
+ };
+ req.onerror = function() {
+ chrome.test.fail('XHR failed: ' + req.status);
+ };
+ req.send(null);
+}
+
+var REMOTE_DEBUGGER_HOST = 'localhost:9222';
+
+function checkTarget(targets, url, type, opt_title, opt_faviconUrl) {
+ var target =
+ targets.filter(function(t) { return t.url == url }) [0];
+ if (!target)
+ chrome.test.fail('Cannot find a target with url ' + url);
+
+ var wsAddress = REMOTE_DEBUGGER_HOST + '/devtools/page/' + target.id;
+
+ chrome.test.assertEq(
+ '/devtools/devtools.html?ws=' + wsAddress,
+ target.devtoolsFrontendUrl);
+ chrome.test.assertEq(opt_faviconUrl || '', target.faviconUrl);
+ chrome.test.assertEq('/thumb/' + target.id, target.thumbnailUrl);
+ chrome.test.assertEq(opt_title || target.url, target.title);
+ chrome.test.assertEq(type, target.type);
+ chrome.test.assertEq('ws://' + wsAddress, target.webSocketDebuggerUrl);
+}
+
+chrome.test.runTests([
+ function discoverTargets() {
+ var testPageUrl = chrome.extension.getURL('test_page.html');
+
+ function onUpdated() {
+ chrome.tabs.onUpdated.removeListener(onUpdated);
+ requestUrl('http://' + REMOTE_DEBUGGER_HOST + '/json', function(text) {
+ var targets = JSON.parse(text);
+
+ checkTarget(targets, 'about:blank', 'page');
+ checkTarget(targets, testPageUrl, 'page', 'Test page',
+ chrome.extension.getURL('favicon.png'));
+ checkTarget(targets,
+ chrome.extension.getURL('_generated_background_page.html'),
+ 'other');
+
+ chrome.test.succeed();
+ });
+ }
+ chrome.tabs.onUpdated.addListener(onUpdated);
+ chrome.tabs.create({url: testPageUrl});
+ }
+]);
diff --git a/chrome/test/data/devtools/target_list/manifest.json b/chrome/test/data/devtools/target_list/manifest.json
new file mode 100644
index 0000000..19dfdfc
--- /dev/null
+++ b/chrome/test/data/devtools/target_list/manifest.json
@@ -0,0 +1,11 @@
+{
+ "name": "Remote Debugger Test",
+ "version": "1.0",
+ "manifest_version": 2,
+ "background": {
+ "scripts": ["background.js"]
+ },
+ "permissions": [
+ "http://*/"
+ ]
+}
diff --git a/chrome/test/data/devtools/target_list/test_page.html b/chrome/test/data/devtools/target_list/test_page.html
new file mode 100644
index 0000000..eb7ed70
--- /dev/null
+++ b/chrome/test/data/devtools/target_list/test_page.html
@@ -0,0 +1,6 @@
+<html>
+<head>
+ <title>Test page</title>
+ <link rel="icon" type="image/png" href="/favicon.png" />
+</head>
+</html>
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
index 0474103..cb2b31e 100644
--- a/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -5,6 +5,7 @@
#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "base/basictypes.h"
+#include "base/stringprintf.h"
#include "content/common/devtools_messages.h"
namespace content {
@@ -15,7 +16,7 @@ static int g_next_agent_host_id = 0;
DevToolsAgentHostImpl::DevToolsAgentHostImpl()
: close_listener_(NULL),
- id_(++g_next_agent_host_id) {
+ id_(base::StringPrintf("%d", ++g_next_agent_host_id)) {
}
void DevToolsAgentHostImpl::Attach() {
@@ -54,6 +55,10 @@ void DevToolsAgentHostImpl::AddMessageToConsole(ConsoleMessageLevel level,
message));
}
+std::string DevToolsAgentHostImpl::GetId() {
+ return id_;
+}
+
RenderViewHost* DevToolsAgentHostImpl::GetRenderViewHost() {
return NULL;
}
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
index c3a5215..5e9cdfb 100644
--- a/content/browser/devtools/devtools_agent_host_impl.h
+++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -41,9 +41,9 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
close_listener_ = listener;
}
- int id() { return id_; }
-
// DevToolsAgentHost implementation.
+ virtual std::string GetId() OVERRIDE;
+
virtual RenderViewHost* GetRenderViewHost() OVERRIDE;
protected:
@@ -59,7 +59,7 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
CloseListener* close_listener_;
private:
- int id_;
+ const std::string id_;
};
} // namespace content
diff --git a/content/browser/devtools/devtools_http_handler_impl.cc b/content/browser/devtools/devtools_http_handler_impl.cc
index 461c51f..3106df0 100644
--- a/content/browser/devtools/devtools_http_handler_impl.cc
+++ b/content/browser/devtools/devtools_http_handler_impl.cc
@@ -15,14 +15,11 @@
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/string_number_conversions.h"
-#include "base/stringprintf.h"
#include "base/threading/thread.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
-#include "content/browser/devtools/devtools_agent_host_impl.h"
#include "content/browser/devtools/devtools_browser_target.h"
#include "content/browser/devtools/devtools_tracing_handler.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/devtools_messages.h"
#include "content/public/browser/browser_thread.h"
@@ -34,9 +31,7 @@
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
-#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/render_widget_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
#include "googleurl/src/gurl.h"
@@ -59,6 +54,8 @@ namespace {
static const char* kDevToolsHandlerThreadName = "Chrome_DevToolsHandlerThread";
+static const char* kThumbUrlPrefix = "/thumb/";
+
class DevToolsDefaultBindingHandler
: public DevToolsHttpHandler::DevToolsAgentHostBinding {
public:
@@ -77,9 +74,7 @@ class DevToolsDefaultBindingHandler
virtual std::string GetIdentifier(DevToolsAgentHost* agent_host) OVERRIDE {
GarbageCollect();
- DevToolsAgentHostImpl* agent_host_impl =
- static_cast<DevToolsAgentHostImpl*>(agent_host);
- std::string id = base::StringPrintf("%d", agent_host_impl->id());
+ std::string id = agent_host->GetId();
agents_map_[id] = agent_host;
return id;
}
@@ -157,6 +152,20 @@ class DevToolsClientHostImpl : public DevToolsClientHost {
std::string detach_reason_;
};
+static base::TimeTicks GetLastSelectedTime(RenderViewHost* rvh) {
+ WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents();
+ if (!web_contents)
+ return base::TimeTicks();
+
+ return web_contents->GetLastSelectedTime();
+}
+
+typedef std::pair<RenderViewHost*, base::TimeTicks> PageInfo;
+
+static bool TimeComparator(const PageInfo& info1, const PageInfo& info2) {
+ return info1.second > info2.second;
+}
+
} // namespace
// static
@@ -308,15 +317,23 @@ void DevToolsHttpHandlerImpl::OnHttpRequest(
return;
}
- if (info.path.find("/thumb/") == 0) {
+ if (info.path.find(kThumbUrlPrefix) == 0) {
// Thumbnail request.
+ const std::string target_id = info.path.substr(strlen(kThumbUrlPrefix));
+ DevToolsAgentHost* agent_host = binding_->ForIdentifier(target_id);
+ GURL page_url;
+ if (agent_host) {
+ RenderViewHost* rvh = agent_host->GetRenderViewHost();
+ if (rvh)
+ page_url = rvh->GetDelegate()->GetURL();
+ }
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&DevToolsHttpHandlerImpl::OnThumbnailRequestUI,
this,
connection_id,
- info));
+ page_url));
return;
}
@@ -395,60 +412,6 @@ void DevToolsHttpHandlerImpl::OnClose(int connection_id) {
connection_id));
}
-struct DevToolsHttpHandlerImpl::PageInfo {
- PageInfo()
- : attached(false) {
- }
-
- std::string id;
- std::string url;
- std::string type;
- bool attached;
- std::string title;
- std::string thumbnail_url;
- std::string favicon_url;
- std::string description;
- base::TimeTicks last_selected_time;
-};
-
-// static
-bool DevToolsHttpHandlerImpl::SortPageListByTime(const PageInfo& info1,
- const PageInfo& info2) {
- return info1.last_selected_time > info2.last_selected_time;
-}
-
-DevToolsHttpHandlerImpl::PageList DevToolsHttpHandlerImpl::GeneratePageList() {
- PageList page_list;
- for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
- !it.IsAtEnd(); it.Advance()) {
- RenderProcessHost* render_process_host = it.GetCurrentValue();
- DCHECK(render_process_host);
-
- // Ignore processes that don't have a connection, such as crashed contents.
- if (!render_process_host->HasConnection())
- continue;
-
- RenderProcessHost::RenderWidgetHostsIterator rwit(
- render_process_host->GetRenderWidgetHostsIterator());
- for (; !rwit.IsAtEnd(); rwit.Advance()) {
- const RenderWidgetHost* widget = rwit.GetCurrentValue();
- DCHECK(widget);
- if (!widget || !widget->IsRenderView())
- continue;
-
- RenderViewHost* host =
- RenderViewHost::From(const_cast<RenderWidgetHost*>(widget));
- // Don't report swapped out views.
- if (static_cast<RenderViewHostImpl*>(host)->is_swapped_out())
- continue;
-
- page_list.push_back(CreatePageInfo(host, delegate_->GetTargetType(host)));
- }
- }
- std::sort(page_list.begin(), page_list.end(), SortPageListByTime);
- return page_list;
-}
-
std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal(
const std::string rvh_id,
const std::string& host) {
@@ -532,11 +495,21 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
}
if (command == "list") {
- PageList page_list = GeneratePageList();
+ typedef std::vector<PageInfo> PageList;
+ PageList page_list;
+
+ std::vector<RenderViewHost*> rvh_list =
+ DevToolsAgentHost::GetValidRenderViewHosts();
+ for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin();
+ it != rvh_list.end(); ++it)
+ page_list.push_back(PageInfo(*it, GetLastSelectedTime(*it)));
+
+ std::sort(page_list.begin(), page_list.end(), TimeComparator);
+
base::ListValue json_pages_list;
std::string host = info.headers["Host"];
for (PageList::iterator i = page_list.begin(); i != page_list.end(); ++i)
- json_pages_list.Append(SerializePageInfo(*i, host));
+ json_pages_list.Append(SerializePageInfo(i->first, host));
SendJson(connection_id, net::HTTP_OK, &json_pages_list, "", jsonp);
return;
}
@@ -551,11 +524,8 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
jsonp);
return;
}
- PageInfo page_info =
- CreatePageInfo(rvh, DevToolsHttpHandlerDelegate::kTargetTypeTab);
std::string host = info.headers["Host"];
- scoped_ptr<base::DictionaryValue> dictionary(
- SerializePageInfo(page_info, host));
+ scoped_ptr<base::DictionaryValue> dictionary(SerializePageInfo(rvh, host));
SendJson(connection_id, net::HTTP_OK, dictionary.get(), "", jsonp);
return;
}
@@ -593,17 +563,8 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
}
void DevToolsHttpHandlerImpl::OnThumbnailRequestUI(
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- std::string prefix = "/thumb/";
- size_t pos = info.path.find(prefix);
- if (pos != 0) {
- Send404(connection_id);
- return;
- }
-
- std::string page_url = info.path.substr(prefix.length());
- std::string data = delegate_->GetPageThumbnailData(GURL(page_url));
+ int connection_id, const GURL& page_url) {
+ std::string data = delegate_->GetPageThumbnailData(page_url);
if (!data.empty())
Send200(connection_id, data, "image/png");
else
@@ -843,66 +804,49 @@ void DevToolsHttpHandlerImpl::AcceptWebSocket(
connection_id, request));
}
-DevToolsHttpHandlerImpl::PageInfo
-DevToolsHttpHandlerImpl::CreatePageInfo(RenderViewHost* rvh,
- DevToolsHttpHandlerDelegate::TargetType type) {
- RenderViewHostDelegate* host_delegate = rvh->GetDelegate();
+base::DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo(
+ RenderViewHost* rvh,
+ const std::string& host) {
+ base::DictionaryValue* dictionary = new base::DictionaryValue;
+
scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetFor(rvh));
- DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
- GetDevToolsClientHostFor(agent);
- PageInfo page_info;
- page_info.id = binding_->GetIdentifier(agent);
- page_info.attached = client_host != NULL;
- page_info.url = host_delegate->GetURL().spec();
-
- switch (type) {
+
+ std::string id = binding_->GetIdentifier(agent);
+ dictionary->SetString("id", id);
+
+ switch (delegate_->GetTargetType(rvh)) {
case DevToolsHttpHandlerDelegate::kTargetTypeTab:
- page_info.type = "page";
+ dictionary->SetString("type", "page");
break;
default:
- page_info.type = "other";
+ dictionary->SetString("type", "other");
}
- WebContents* web_contents = host_delegate->GetAsWebContents();
+ WebContents* web_contents = rvh->GetDelegate()->GetAsWebContents();
if (web_contents) {
- page_info.title = UTF16ToUTF8(
- net::EscapeForHTML(web_contents->GetTitle()));
- page_info.last_selected_time = web_contents->GetLastSelectedTime();
+ dictionary->SetString("title", UTF16ToUTF8(
+ net::EscapeForHTML(web_contents->GetTitle())));
+ dictionary->SetString("url", web_contents->GetURL().spec());
+ dictionary->SetString("thumbnailUrl", std::string(kThumbUrlPrefix) + id);
NavigationController& controller = web_contents->GetController();
NavigationEntry* entry = controller.GetActiveEntry();
if (entry != NULL && entry->GetURL().is_valid()) {
- page_info.thumbnail_url = "/thumb/" + entry->GetURL().spec();
- page_info.favicon_url = entry->GetFavicon().url.spec();
+ dictionary->SetString("faviconUrl", entry->GetFavicon().url.spec());
}
}
- page_info.description = delegate_->GetViewDescription(rvh);
-
- return page_info;
-}
-
-base::DictionaryValue* DevToolsHttpHandlerImpl::SerializePageInfo(
- const PageInfo& page_info,
- const std::string& host) {
- base::DictionaryValue* dictionary = new base::DictionaryValue;
- dictionary->SetString("title", page_info.title);
- dictionary->SetString("url", page_info.url);
- dictionary->SetString("type", page_info.type);
- dictionary->SetString("id", page_info.id);
- dictionary->SetString("thumbnailUrl", page_info.thumbnail_url);
- dictionary->SetString("faviconUrl", page_info.favicon_url);
- if (!page_info.attached) {
+ if (!DevToolsManager::GetInstance()->GetDevToolsClientHostFor(agent)) {
dictionary->SetString("webSocketDebuggerUrl",
base::StringPrintf("ws://%s/devtools/page/%s",
host.c_str(),
- page_info.id.c_str()));
+ id.c_str()));
std::string devtools_frontend_url = GetFrontendURLInternal(
- page_info.id.c_str(),
+ id.c_str(),
host);
dictionary->SetString("devtoolsFrontendUrl", devtools_frontend_url);
}
- dictionary->SetString("description", page_info.description);
+ dictionary->SetString("description", delegate_->GetViewDescription(rvh));
return dictionary;
}
diff --git a/content/browser/devtools/devtools_http_handler_impl.h b/content/browser/devtools/devtools_http_handler_impl.h
index dd027ee..77d7283 100644
--- a/content/browser/devtools/devtools_http_handler_impl.h
+++ b/content/browser/devtools/devtools_http_handler_impl.h
@@ -41,13 +41,9 @@ class DevToolsHttpHandlerImpl
public base::RefCountedThreadSafe<DevToolsHttpHandlerImpl>,
public net::HttpServer::Delegate {
private:
- struct PageInfo;
- typedef std::vector<PageInfo> PageList;
friend class base::RefCountedThreadSafe<DevToolsHttpHandlerImpl>;
friend class DevToolsHttpHandler;
- static bool SortPageListByTime(const PageInfo& info1, const PageInfo& info2);
-
// Takes ownership over |socket_factory|.
DevToolsHttpHandlerImpl(const net::StreamListenSocketFactory* socket_factory,
const std::string& frontend_url,
@@ -78,8 +74,7 @@ class DevToolsHttpHandlerImpl
void OnJsonRequestUI(int connection_id,
const net::HttpServerRequestInfo& info);
- void OnThumbnailRequestUI(int connection_id,
- const net::HttpServerRequestInfo& info);
+ void OnThumbnailRequestUI(int connection_id, const GURL& page_url);
void OnDiscoveryPageRequestUI(int connection_id);
void OnWebSocketRequestUI(int connection_id,
@@ -110,16 +105,11 @@ class DevToolsHttpHandlerImpl
void AcceptWebSocket(int connection_id,
const net::HttpServerRequestInfo& request);
- PageList GeneratePageList();
-
// Returns the front end url without the host at the beginning.
std::string GetFrontendURLInternal(const std::string rvh_id,
const std::string& host);
- PageInfo CreatePageInfo(RenderViewHost* rvh,
- DevToolsHttpHandlerDelegate::TargetType type);
-
- base::DictionaryValue* SerializePageInfo(const PageInfo& page_info,
+ base::DictionaryValue* SerializePageInfo(RenderViewHost* rvh,
const std::string& host);
// The thread used by the devtools handler to run server socket.
diff --git a/content/browser/devtools/render_view_devtools_agent_host.cc b/content/browser/devtools/render_view_devtools_agent_host.cc
index 26b14bf..6bbb103 100644
--- a/content/browser/devtools/render_view_devtools_agent_host.cc
+++ b/content/browser/devtools/render_view_devtools_agent_host.cc
@@ -104,32 +104,64 @@ bool DevToolsAgentHost::IsDebuggerAttached(WebContents* web_contents) {
}
// static
-int DevToolsAgentHost::DisconnectRenderViewHost(RenderViewHost* rvh) {
+std::string DevToolsAgentHost::DisconnectRenderViewHost(RenderViewHost* rvh) {
RenderViewDevToolsAgentHost* agent_host = FindAgentHost(rvh);
if (!agent_host)
- return -1;
+ return std::string();
agent_host->DisconnectRenderViewHost();
- return agent_host->id();
+ return agent_host->GetId();
}
// static
-void DevToolsAgentHost::ConnectRenderViewHost(int cookie,
+void DevToolsAgentHost::ConnectRenderViewHost(const std::string& cookie,
RenderViewHost* rvh) {
for (Instances::iterator it = g_instances.Get().begin();
it != g_instances.Get().end(); ++it) {
- if (cookie == (*it)->id()) {
+ if (cookie == (*it)->GetId()) {
(*it)->ConnectRenderViewHost(rvh, true);
break;
}
}
}
+//static
+std::vector<RenderViewHost*> DevToolsAgentHost::GetValidRenderViewHosts() {
+ std::vector<RenderViewHost*> result;
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ RenderProcessHost* render_process_host = it.GetCurrentValue();
+ DCHECK(render_process_host);
+
+ // Ignore processes that don't have a connection, such as crashed contents.
+ if (!render_process_host->HasConnection())
+ continue;
+
+ RenderProcessHost::RenderWidgetHostsIterator rwit(
+ render_process_host->GetRenderWidgetHostsIterator());
+ for (; !rwit.IsAtEnd(); rwit.Advance()) {
+ const RenderWidgetHost* widget = rwit.GetCurrentValue();
+ DCHECK(widget);
+ if (!widget || !widget->IsRenderView())
+ continue;
+
+ RenderViewHost* rvh =
+ RenderViewHost::From(const_cast<RenderWidgetHost*>(widget));
+ // Don't report swapped out views.
+ if (static_cast<RenderViewHostImpl*>(rvh)->is_swapped_out())
+ continue;
+
+ result.push_back(rvh);
+ }
+ }
+ return result;
+}
+
// static
void RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
RenderViewHost* pending,
RenderViewHost* current) {
- int cookie = DevToolsAgentHost::DisconnectRenderViewHost(pending);
- if (cookie != -1)
+ std::string cookie = DevToolsAgentHost::DisconnectRenderViewHost(pending);
+ if (cookie != std::string())
DevToolsAgentHost::ConnectRenderViewHost(cookie, current);
}
diff --git a/content/public/browser/devtools_agent_host.h b/content/public/browser/devtools_agent_host.h
index 533c31d..8395b2d 100644
--- a/content/public/browser/devtools_agent_host.h
+++ b/content/public/browser/devtools_agent_host.h
@@ -6,6 +6,7 @@
#define CONTENT_PUBLIC_BROWSER_DEVTOOLS_AGENT_HOST_H_
#include <string>
+#include <vector>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
@@ -35,16 +36,22 @@ class CONTENT_EXPORT DevToolsAgentHost
static bool IsDebuggerAttached(WebContents* web_contents);
- // Detaches given |rvh| from the agent host temporarily and returns a cookie
- // that allows to reattach another rvh to that agen thost later. Returns -1 if
- // there is no agent host associated with the |rvh|.
- static int DisconnectRenderViewHost(RenderViewHost* rvh);
+ // Detaches given |rvh| from the agent host temporarily and returns the agent
+ // host id that allows to reattach another rvh to that agent host later.
+ // Returns empty string if there is no agent host associated with the |rvh|.
+ static std::string DisconnectRenderViewHost(RenderViewHost* rvh);
// Reattaches agent host detached with DisconnectRenderViewHost method above
// to |rvh|.
- static void ConnectRenderViewHost(int agent_host_cookie,
+ static void ConnectRenderViewHost(const std::string& agent_host_cookie,
RenderViewHost* rvh);
+ // Returns a list of all existing RenderViewHost's that can be debugged.
+ static std::vector<RenderViewHost*> GetValidRenderViewHosts();
+
+ // Returns the unique id of the agent.
+ virtual std::string GetId() = 0;
+
// Returns render view host instance for this host if any.
virtual RenderViewHost* GetRenderViewHost() = 0;