summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-16 12:20:43 +0000
committerpfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-16 12:20:43 +0000
commit87b92ddd35ebafecb9ebc9b95729b0b7f26d62c6 (patch)
tree5d1b8b5491712a7fbad780ca2cc898a3f2a14eda
parenta67b226205d6e589cb2aa930c963a2950329ec1d (diff)
downloadchromium_src-87b92ddd35ebafecb9ebc9b95729b0b7f26d62c6.zip
chromium_src-87b92ddd35ebafecb9ebc9b95729b0b7f26d62c6.tar.gz
chromium_src-87b92ddd35ebafecb9ebc9b95729b0b7f26d62c6.tar.bz2
DevTools: allow remote debugging any RenderViewHost.
BUG=118390 Review URL: https://chromiumcodereview.appspot.com/9699073 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127155 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/debugger/browser_list_tabcontents_provider.cc54
-rw-r--r--chrome/browser/debugger/browser_list_tabcontents_provider.h18
-rw-r--r--content/browser/debugger/devtools_http_handler_impl.cc166
-rw-r--r--content/browser/debugger/devtools_http_handler_impl.h13
-rw-r--r--content/public/browser/devtools_http_handler_delegate.h3
-rw-r--r--content/shell/shell_content_browser_client.cc4
-rw-r--r--content/shell/shell_devtools_delegate.cc23
-rw-r--r--content/shell/shell_devtools_delegate.h14
8 files changed, 96 insertions, 199 deletions
diff --git a/chrome/browser/debugger/browser_list_tabcontents_provider.cc b/chrome/browser/debugger/browser_list_tabcontents_provider.cc
index ca37cd5..fbd2d77 100644
--- a/chrome/browser/debugger/browser_list_tabcontents_provider.cc
+++ b/chrome/browser/debugger/browser_list_tabcontents_provider.cc
@@ -6,13 +6,8 @@
#include "chrome/browser/history/top_sites.h"
#include "chrome/browser/profiles/profile.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/public/browser/browser_thread.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/notification_types.h"
#include "grit/devtools_discovery_page_resources.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/resource/resource_bundle.h"
@@ -20,41 +15,11 @@
using content::DevToolsHttpHandlerDelegate;
BrowserListTabContentsProvider::BrowserListTabContentsProvider() {
- registrar_.Add(this,
- content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
- content::NotificationService::AllSources());
- registrar_.Add(this,
- content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
- content::NotificationService::AllSources());
- registrar_.Add(this,
- content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
- content::NotificationService::AllSources());
-
}
BrowserListTabContentsProvider::~BrowserListTabContentsProvider() {
}
-DevToolsHttpHandlerDelegate::InspectableTabs
-BrowserListTabContentsProvider::GetInspectableTabs() {
- DevToolsHttpHandlerDelegate::InspectableTabs tabs;
- // Add the tabs from all browsers first.
- 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)->web_contents());
- }
-
- // Then add any extra WebContents that have been observed.
- for (std::set<content::WebContents*>::iterator it = contents_.begin();
- it != contents_.end(); ++it) {
- if (std::find(tabs.begin(), tabs.end(), *it) == tabs.end())
- tabs.push_back(*it);
- }
- return tabs;
-}
-
std::string BrowserListTabContentsProvider::GetDiscoveryPageHTML() {
std::set<Profile*> profiles;
for (BrowserList::const_iterator it = BrowserList::begin(),
@@ -94,22 +59,3 @@ bool BrowserListTabContentsProvider::BundlesFrontendResources() {
std::string BrowserListTabContentsProvider::GetFrontendResourcesBaseURL() {
return "chrome-devtools://devtools/";
}
-
-void BrowserListTabContentsProvider::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- content::WebContents* web_contents =
- content::Source<content::WebContents>(source).ptr();
- switch (type) {
- case content::NOTIFICATION_WEB_CONTENTS_CONNECTED:
- contents_.insert(web_contents);
- break;
- case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
- case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
- contents_.erase(web_contents);
- break;
- default:
- NOTREACHED();
- return;
- }
-}
diff --git a/chrome/browser/debugger/browser_list_tabcontents_provider.h b/chrome/browser/debugger/browser_list_tabcontents_provider.h
index 2745e0e..58d149f 100644
--- a/chrome/browser/debugger/browser_list_tabcontents_provider.h
+++ b/chrome/browser/debugger/browser_list_tabcontents_provider.h
@@ -11,40 +11,24 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
namespace content {
class WebContents;
}
class BrowserListTabContentsProvider
- : public content::DevToolsHttpHandlerDelegate,
- public content::NotificationObserver {
+ : public content::DevToolsHttpHandlerDelegate {
public:
BrowserListTabContentsProvider();
virtual ~BrowserListTabContentsProvider();
// DevToolsHttpProtocolHandler::Delegate overrides.
- virtual DevToolsHttpHandlerDelegate::InspectableTabs
- GetInspectableTabs() OVERRIDE;
virtual std::string GetDiscoveryPageHTML() OVERRIDE;
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
virtual bool BundlesFrontendResources() OVERRIDE;
virtual std::string GetFrontendResourcesBaseURL() OVERRIDE;
private:
- // content::NotificationObserver overrides.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
-
- // The set of tab contents which can be inspected.
- std::set<content::WebContents*> contents_;
-
- // A scoped container for notification registries.
- content::NotificationRegistrar registrar_;
-
DISALLOW_COPY_AND_ASSIGN(BrowserListTabContentsProvider);
};
diff --git a/content/browser/debugger/devtools_http_handler_impl.cc b/content/browser/debugger/devtools_http_handler_impl.cc
index 4cdb6b0..0365527 100644
--- a/content/browser/debugger/devtools_http_handler_impl.cc
+++ b/content/browser/debugger/devtools_http_handler_impl.cc
@@ -26,6 +26,9 @@
#include "content/public/browser/devtools_manager.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_entry.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/browser/web_contents_observer.h"
#include "content/public/common/content_client.h"
#include "googleurl/src/gurl.h"
@@ -80,55 +83,6 @@ class DevToolsClientHostImpl : public DevToolsClientHost {
int connection_id_;
};
-static int next_id = 1;
-
-class TabContentsIDHelper : public content::WebContentsObserver {
- public:
- static int GetID(TabContents* contents) {
- TabContentsToIdMap::iterator it = tab_contents_to_id_.Get().find(contents);
- if (it != tab_contents_to_id_.Get().end())
- return it->second;
- TabContentsIDHelper* wrapper = new TabContentsIDHelper(contents);
- return wrapper->id_;
- }
-
- static TabContents* GetTabContents(int id) {
- IdToTabContentsMap::iterator it = id_to_tab_contents_.Get().find(id);
- if (it != id_to_tab_contents_.Get().end())
- return it->second;
- return NULL;
- }
-
- private:
- explicit TabContentsIDHelper(TabContents* tab)
- : content::WebContentsObserver(tab),
- id_(next_id++) {
- id_to_tab_contents_.Get()[id_] = tab;
- tab_contents_to_id_.Get()[tab] = id_;
- }
-
- virtual ~TabContentsIDHelper() {}
-
- virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE {
- id_to_tab_contents_.Get().erase(id_);
- tab_contents_to_id_.Get().erase((static_cast<TabContents*>(contents)));
- delete this;
- }
-
- int id_;
- typedef std::map<int, TabContents*> IdToTabContentsMap;
- static base::LazyInstance<IdToTabContentsMap>::Leaky
- id_to_tab_contents_;
- typedef std::map<TabContents*, int> TabContentsToIdMap;
- static base::LazyInstance<TabContentsToIdMap>::Leaky
- tab_contents_to_id_;
-};
-
-base::LazyInstance<TabContentsIDHelper::IdToTabContentsMap>::Leaky
- TabContentsIDHelper::id_to_tab_contents_ = LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<TabContentsIDHelper::TabContentsToIdMap>::Leaky
- TabContentsIDHelper::tab_contents_to_id_ = LAZY_INSTANCE_INITIALIZER;
-
} // namespace
// static
@@ -302,8 +256,13 @@ void DevToolsHttpHandlerImpl::OnClose(int connection_id) {
connection_id));
}
-struct PageInfo
+struct DevToolsHttpHandlerImpl::PageInfo
{
+ PageInfo()
+ : id(0),
+ attached(false) {
+ }
+
int id;
std::string url;
bool attached;
@@ -312,44 +271,61 @@ struct PageInfo
std::string favicon_url;
base::TimeTicks last_selected_time;
};
-typedef std::vector<PageInfo> PageList;
-static bool SortPageListByTime(const PageInfo& info1, const PageInfo& info2) {
+// static
+bool DevToolsHttpHandlerImpl::SortPageListByTime(const PageInfo& info1,
+ const PageInfo& info2) {
return info1.last_selected_time > info2.last_selected_time;
}
-static PageList GeneratePageList(
- DevToolsHttpHandlerDelegate* delegate,
- int connection_id,
- const net::HttpServerRequestInfo& info) {
- typedef DevToolsHttpHandlerDelegate::InspectableTabs Tabs;
- Tabs inspectable_tabs = delegate->GetInspectableTabs();
-
+DevToolsHttpHandlerImpl::PageList DevToolsHttpHandlerImpl::GeneratePageList() {
+ ResetRenderViewHostBinding();
PageList page_list;
- for (Tabs::iterator it = inspectable_tabs.begin();
- it != inspectable_tabs.end(); ++it) {
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+ !it.IsAtEnd(); it.Advance()) {
+ RenderProcessHost* render_process_host = it.GetCurrentValue();
+ DCHECK(render_process_host);
- WebContents* web_contents = *it;
- NavigationController& controller = web_contents->GetController();
-
- NavigationEntry* entry = controller.GetActiveEntry();
- if (entry == NULL || !entry->GetURL().is_valid())
+ // Ignore processes that don't have a connection, such as crashed tabs.
+ if (!render_process_host->HasConnection())
continue;
- DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost(
- web_contents->GetRenderViewHost());
- DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
- GetDevToolsClientHostFor(agent);
- PageInfo page_info;
- page_info.id = TabContentsIDHelper::GetID(
- static_cast<TabContents*>(web_contents));
- page_info.attached = client_host != NULL;
- page_info.url = entry->GetURL().spec();
- page_info.title = UTF16ToUTF8(net::EscapeForHTML(entry->GetTitle()));
- page_info.thumbnail_url = "/thumb/" + entry->GetURL().spec();
- page_info.favicon_url = entry->GetFavicon().url.spec();
- page_info.last_selected_time = web_contents->GetLastSelectedTime();
- page_list.push_back(page_info);
+ 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));
+ content::RenderViewHostDelegate* host_delegate = host->GetDelegate();
+
+ DevToolsAgentHost* agent =
+ DevToolsAgentHostRegistry::GetDevToolsAgentHost(host);
+ DevToolsClientHost* client_host = DevToolsManager::GetInstance()->
+ GetDevToolsClientHostFor(agent);
+ PageInfo page_info;
+ page_info.id = BindRenderViewHost(host);
+ page_info.attached = client_host != NULL;
+ page_info.url = host_delegate->GetURL().spec();
+
+ WebContents* web_contents = host_delegate->GetAsWebContents();
+ if (web_contents) {
+ page_info.title = UTF16ToUTF8(
+ net::EscapeForHTML(web_contents->GetTitle()));
+ page_info.last_selected_time = web_contents->GetLastSelectedTime();
+
+ 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();
+ }
+ }
+ page_list.push_back(page_info);
+ }
}
std::sort(page_list.begin(), page_list.end(), SortPageListByTime);
return page_list;
@@ -358,8 +334,7 @@ static PageList GeneratePageList(
void DevToolsHttpHandlerImpl::OnJsonRequestUI(
int connection_id,
const net::HttpServerRequestInfo& info) {
- PageList page_list = GeneratePageList(delegate_.get(),
- connection_id, info);
+ PageList page_list = GeneratePageList();
ListValue json_pages_list;
std::string host = info.headers["Host"];
for (PageList::iterator i = page_list.begin();
@@ -409,17 +384,18 @@ void DevToolsHttpHandlerImpl::OnWebSocketRequestUI(
return;
}
- TabContents* web_contents = TabContentsIDHelper::GetTabContents(id);
- if (web_contents == NULL) {
- Send500(connection_id, "No such page id: " + page_id);
+ RenderViewHost* rvh = GetBoundRenderViewHost(id);
+ if (!rvh) {
+ Send500(connection_id, "No such target id: " + page_id);
return;
}
DevToolsManager* manager = DevToolsManager::GetInstance();
DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost(
- web_contents->GetRenderViewHost());
+ rvh);
if (manager->GetDevToolsClientHostFor(agent)) {
- Send500(connection_id, "Page with given id is being inspected: " + page_id);
+ Send500(connection_id, "Target with given id is being inspected: " +
+ page_id);
return;
}
@@ -605,4 +581,20 @@ void DevToolsHttpHandlerImpl::AcceptWebSocket(
connection_id, request));
}
+size_t DevToolsHttpHandlerImpl::BindRenderViewHost(RenderViewHost* rvh) {
+ Target target = std::make_pair(rvh->GetProcess()->GetID(),
+ rvh->GetRoutingID());
+ targets_.push_back(target);
+ return targets_.size() - 1;
+}
+
+RenderViewHost* DevToolsHttpHandlerImpl::GetBoundRenderViewHost(size_t id) {
+ return RenderViewHost::FromID(targets_[id].first,
+ targets_[id].second);
+}
+
+void DevToolsHttpHandlerImpl::ResetRenderViewHostBinding() {
+ targets_.clear();
+}
+
} // namespace content
diff --git a/content/browser/debugger/devtools_http_handler_impl.h b/content/browser/debugger/devtools_http_handler_impl.h
index 556ab06d..67f91ea 100644
--- a/content/browser/debugger/devtools_http_handler_impl.h
+++ b/content/browser/debugger/devtools_http_handler_impl.h
@@ -25,6 +25,7 @@ class URLRequestContext;
namespace content {
class DevToolsClientHost;
+class RenderViewHost;
class DevToolsHttpHandlerImpl
: public DevToolsHttpHandler,
@@ -32,8 +33,13 @@ class DevToolsHttpHandlerImpl
public net::HttpServer::Delegate,
public net::URLRequest::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);
+
DevToolsHttpHandlerImpl(const std::string& ip,
int port,
const std::string& frontend_url,
@@ -54,6 +60,8 @@ class DevToolsHttpHandlerImpl
const std::string& data) OVERRIDE;
virtual void OnClose(int connection_id) OVERRIDE;
+ PageList GeneratePageList();
+
virtual void OnJsonRequestUI(int connection_id,
const net::HttpServerRequestInfo& info);
virtual void OnWebSocketRequestUI(int connection_id,
@@ -80,6 +88,9 @@ class DevToolsHttpHandlerImpl
const std::string& message);
void AcceptWebSocket(int connection_id,
const net::HttpServerRequestInfo& request);
+ size_t BindRenderViewHost(RenderViewHost* rvh);
+ RenderViewHost* GetBoundRenderViewHost(size_t id);
+ void ResetRenderViewHostBinding();
std::string ip_;
int port_;
@@ -98,6 +109,8 @@ class DevToolsHttpHandlerImpl
ConnectionToClientHostMap;
ConnectionToClientHostMap connection_to_client_host_ui_;
scoped_ptr<DevToolsHttpHandlerDelegate> delegate_;
+ typedef std::pair<int, int> Target;
+ std::vector<Target> targets_;
DISALLOW_COPY_AND_ASSIGN(DevToolsHttpHandlerImpl);
};
diff --git a/content/public/browser/devtools_http_handler_delegate.h b/content/public/browser/devtools_http_handler_delegate.h
index 42f9e33..e0f9f5f 100644
--- a/content/public/browser/devtools_http_handler_delegate.h
+++ b/content/public/browser/devtools_http_handler_delegate.h
@@ -22,9 +22,6 @@ class DevToolsHttpHandlerDelegate {
typedef std::vector<WebContents*> InspectableTabs;
virtual ~DevToolsHttpHandlerDelegate() {}
- // Should return the list of inspectable tabs. Called on the UI thread.
- virtual InspectableTabs GetInspectableTabs() = 0;
-
// Should return discovery page HTML that should list available tabs
// and provide attach links. Called on the IO thread.
virtual std::string GetDiscoveryPageHTML() = 0;
diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc
index 686e6ce..1991fbd 100644
--- a/content/shell/shell_content_browser_client.cc
+++ b/content/shell/shell_content_browser_client.cc
@@ -40,10 +40,6 @@ BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
WebContentsView* ShellContentBrowserClient::OverrideCreateWebContentsView(
WebContents* web_contents) {
- ShellDevToolsDelegate* devtools_delegate =
- shell_browser_main_parts_->devtools_delegate();
- if (devtools_delegate)
- devtools_delegate->AddWebContents(web_contents);
return NULL;
}
diff --git a/content/shell/shell_devtools_delegate.cc b/content/shell/shell_devtools_delegate.cc
index 597b4cc..b16777c 100644
--- a/content/shell/shell_devtools_delegate.cc
+++ b/content/shell/shell_devtools_delegate.cc
@@ -7,7 +7,6 @@
#include <algorithm>
#include "content/public/browser/devtools_http_handler.h"
-#include "content/public/browser/web_contents.h"
#include "grit/shell_resources.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/base/resource/resource_bundle.h"
@@ -17,8 +16,7 @@ namespace content {
ShellDevToolsDelegate::ShellDevToolsDelegate(
int port,
net::URLRequestContextGetter* context_getter)
- : content::WebContentsObserver(),
- context_getter_(context_getter) {
+ : context_getter_(context_getter) {
devtools_http_handler_ = DevToolsHttpHandler::Start(
"127.0.0.1",
port,
@@ -34,20 +32,6 @@ void ShellDevToolsDelegate::Stop() {
devtools_http_handler_->Stop();
}
-void ShellDevToolsDelegate::WebContentsDestroyed(WebContents* contents) {
- std::remove(web_contents_list_.begin(), web_contents_list_.end(), contents);
-}
-
-DevToolsHttpHandlerDelegate::InspectableTabs
-ShellDevToolsDelegate::GetInspectableTabs() {
- DevToolsHttpHandlerDelegate::InspectableTabs tabs;
- for (std::vector<WebContents*>::iterator it = web_contents_list_.begin();
- it != web_contents_list_.end(); ++it) {
- tabs.push_back(*it);
- }
- return tabs;
-}
-
std::string ShellDevToolsDelegate::GetDiscoveryPageHTML() {
return ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_CONTENT_SHELL_DEVTOOLS_DISCOVERY_PAGE).as_string();
@@ -66,9 +50,4 @@ std::string ShellDevToolsDelegate::GetFrontendResourcesBaseURL() {
return "";
}
-void ShellDevToolsDelegate::AddWebContents(WebContents* web_contents) {
- web_contents_list_.push_back(web_contents);
- Observe(web_contents);
-}
-
} // namespace content
diff --git a/content/shell/shell_devtools_delegate.h b/content/shell/shell_devtools_delegate.h
index 42f85ae..2f37439 100644
--- a/content/shell/shell_devtools_delegate.h
+++ b/content/shell/shell_devtools_delegate.h
@@ -8,9 +8,9 @@
#include <vector>
+#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "content/public/browser/devtools_http_handler_delegate.h"
-#include "content/public/browser/web_contents_observer.h"
namespace net {
class URLRequestContextGetter;
@@ -20,9 +20,7 @@ namespace content {
class DevToolsHttpHandler;
-class ShellDevToolsDelegate
- : public content::DevToolsHttpHandlerDelegate,
- public content::WebContentsObserver {
+class ShellDevToolsDelegate : public content::DevToolsHttpHandlerDelegate {
public:
ShellDevToolsDelegate(int port, net::URLRequestContextGetter* context_getter);
virtual ~ShellDevToolsDelegate();
@@ -30,21 +28,13 @@ class ShellDevToolsDelegate
// Stops http server.
void Stop();
- // WebContentsObserver overrides.
- virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE;
-
// DevToolsHttpProtocolHandler::Delegate overrides.
- virtual DevToolsHttpHandlerDelegate::InspectableTabs
- GetInspectableTabs() OVERRIDE;
virtual std::string GetDiscoveryPageHTML() OVERRIDE;
virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
virtual bool BundlesFrontendResources() OVERRIDE;
virtual std::string GetFrontendResourcesBaseURL() OVERRIDE;
- void AddWebContents(WebContents* web_contents);
-
private:
- std::vector<WebContents*> web_contents_list_;
net::URLRequestContextGetter* context_getter_;
DevToolsHttpHandler* devtools_http_handler_;