diff options
author | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-16 12:20:43 +0000 |
---|---|---|
committer | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-16 12:20:43 +0000 |
commit | 87b92ddd35ebafecb9ebc9b95729b0b7f26d62c6 (patch) | |
tree | 5d1b8b5491712a7fbad780ca2cc898a3f2a14eda | |
parent | a67b226205d6e589cb2aa930c963a2950329ec1d (diff) | |
download | chromium_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.cc | 54 | ||||
-rw-r--r-- | chrome/browser/debugger/browser_list_tabcontents_provider.h | 18 | ||||
-rw-r--r-- | content/browser/debugger/devtools_http_handler_impl.cc | 166 | ||||
-rw-r--r-- | content/browser/debugger/devtools_http_handler_impl.h | 13 | ||||
-rw-r--r-- | content/public/browser/devtools_http_handler_delegate.h | 3 | ||||
-rw-r--r-- | content/shell/shell_content_browser_client.cc | 4 | ||||
-rw-r--r-- | content/shell/shell_devtools_delegate.cc | 23 | ||||
-rw-r--r-- | content/shell/shell_devtools_delegate.h | 14 |
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_; |