#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/devtools/devtools_window.h"
-#include "chrome/browser/extensions/extension_host.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
+#include "extensions/browser/extension_host.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/guest_view/guest_view_base.h"
+#include "extensions/browser/process_manager.h"
+#include "extensions/common/constants.h"
using content::BrowserThread;
using content::DevToolsAgentHost;
using content::WebContents;
using content::WorkerService;
+const char DevToolsTargetImpl::kTargetTypeApp[] = "app";
+const char DevToolsTargetImpl::kTargetTypeBackgroundPage[] = "background_page";
+const char DevToolsTargetImpl::kTargetTypePage[] = "page";
+const char DevToolsTargetImpl::kTargetTypeWorker[] = "worker";
+const char DevToolsTargetImpl::kTargetTypeWebView[] = "webview";
+const char DevToolsTargetImpl::kTargetTypeIFrame[] = "iframe";
+const char DevToolsTargetImpl::kTargetTypeOther[] = "other";
+const char DevToolsTargetImpl::kTargetTypeServiceWorker[] = "service_worker";
+
namespace {
-const char kTargetTypeApp[] = "app";
-const char kTargetTypeBackgroundPage[] = "background_page";
-const char kTargetTypePage[] = "page";
-const char kTargetTypeWorker[] = "worker";
-const char kTargetTypeOther[] = "other";
+// WebContentsTarget --------------------------------------------------------
-class RenderViewHostTarget : public DevToolsTargetImpl {
+class WebContentsTarget : public DevToolsTargetImpl {
public:
- explicit RenderViewHostTarget(RenderViewHost* rvh, bool is_tab);
-
- // content::DevToolsTarget overrides:
- virtual bool Activate() const OVERRIDE;
- virtual bool Close() const OVERRIDE;
+ WebContentsTarget(WebContents* web_contents, bool is_tab);
// DevToolsTargetImpl overrides:
- virtual RenderViewHost* GetRenderViewHost() const OVERRIDE;
- virtual int GetTabId() const OVERRIDE;
- virtual std::string GetExtensionId() const OVERRIDE;
- virtual void Inspect(Profile* profile) const OVERRIDE;
+ WebContents* GetWebContents() const override;
+ int GetTabId() const override;
+ std::string GetExtensionId() const override;
+ void Inspect(Profile* profile) const override;
private:
int tab_id_;
std::string extension_id_;
};
-RenderViewHostTarget::RenderViewHostTarget(RenderViewHost* rvh, bool is_tab) {
- agent_host_ = DevToolsAgentHost::GetOrCreateFor(rvh);
- id_ = agent_host_->GetId();
- type_ = kTargetTypeOther;
- tab_id_ = -1;
-
- WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
- if (!web_contents)
- return; // Orphan RVH will show up with no title/url/icon in clients.
+WebContentsTarget::WebContentsTarget(WebContents* web_contents, bool is_tab)
+ : DevToolsTargetImpl(DevToolsAgentHost::GetOrCreateFor(web_contents)),
+ tab_id_(-1) {
+ set_type(kTargetTypeOther);
+
+ content::RenderFrameHost* rfh =
+ web_contents->GetRenderViewHost()->GetMainFrame();
+ if (rfh->IsCrossProcessSubframe()) {
+ set_url(rfh->GetLastCommittedURL());
+ set_type(kTargetTypeIFrame);
+ // TODO(pfeldman) Update for out of process iframes.
+ RenderViewHost* parent_rvh = rfh->GetParent()->GetRenderViewHost();
+ set_parent_id(DevToolsAgentHost::GetOrCreateFor(
+ WebContents::FromRenderViewHost(parent_rvh))->GetId());
+ return;
+ }
- title_ = base::UTF16ToUTF8(web_contents->GetTitle());
- url_ = web_contents->GetURL();
content::NavigationController& controller = web_contents->GetController();
content::NavigationEntry* entry = controller.GetActiveEntry();
if (entry != NULL && entry->GetURL().is_valid())
- favicon_url_ = entry->GetFavicon().url;
- last_activity_time_ = web_contents->GetLastSelectedTime();
+ set_favicon_url(entry->GetFavicon().url);
+ set_last_activity_time(web_contents->GetLastActiveTime());
+
+ extensions::GuestViewBase* guest =
+ extensions::GuestViewBase::FromWebContents(web_contents);
+ WebContents* guest_contents = guest ? guest->embedder_web_contents() : NULL;
+ if (guest_contents) {
+ set_type(kTargetTypeWebView);
+ set_parent_id(DevToolsAgentHost::GetOrCreateFor(guest_contents)->GetId());
+ return;
+ }
if (is_tab) {
- type_ = kTargetTypePage;
+ set_type(kTargetTypePage);
tab_id_ = extensions::ExtensionTabUtil::GetTabId(web_contents);
- } else {
- Profile* profile =
- Profile::FromBrowserContext(web_contents->GetBrowserContext());
- if (profile) {
- ExtensionService* extension_service = profile->GetExtensionService();
- const extensions::Extension* extension = extension_service->
- extensions()->GetByID(url_.host());
- if (extension) {
- title_ = extension->name();
- extensions::ExtensionHost* extension_host =
- extensions::ExtensionSystem::Get(profile)->process_manager()->
- GetBackgroundHostForExtension(extension->id());
- if (extension_host &&
- extension_host->host_contents() == web_contents) {
- type_ = kTargetTypeBackgroundPage;
- extension_id_ = extension->id();
- } else if (extension->is_hosted_app()
- || extension->is_legacy_packaged_app()
- || extension->is_platform_app()) {
- type_ = kTargetTypeApp;
- }
- favicon_url_ = extensions::ExtensionIconSource::GetIconURL(
- extension, extension_misc::EXTENSION_ICON_SMALLISH,
- ExtensionIconSet::MATCH_BIGGER, false, NULL);
- }
- }
+ return;
}
-}
-bool RenderViewHostTarget::Activate() const {
- RenderViewHost* rvh = GetRenderViewHost();
- if (!rvh)
- return false;
- WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
- if (!web_contents)
- return false;
- web_contents->GetDelegate()->ActivateContents(web_contents);
- return true;
-}
+ const extensions::Extension* extension = extensions::ExtensionRegistry::Get(
+ web_contents->GetBrowserContext())->enabled_extensions().GetByID(
+ GetURL().host());
+ if (!extension)
+ return;
-bool RenderViewHostTarget::Close() const {
- RenderViewHost* rvh = GetRenderViewHost();
- if (!rvh)
- return false;
- rvh->ClosePage();
- return true;
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext());
+ if (!profile)
+ return;
+ set_title(extension->name());
+ extensions::ExtensionHost* extension_host =
+ extensions::ProcessManager::Get(profile)
+ ->GetBackgroundHostForExtension(extension->id());
+ if (extension_host &&
+ extension_host->host_contents() == web_contents) {
+ set_type(kTargetTypeBackgroundPage);
+ extension_id_ = extension->id();
+ } else if (extension->is_hosted_app()
+ || extension->is_legacy_packaged_app()
+ || extension->is_platform_app()) {
+ set_type(kTargetTypeApp);
+ }
+ set_favicon_url(extensions::ExtensionIconSource::GetIconURL(
+ extension, extension_misc::EXTENSION_ICON_SMALLISH,
+ ExtensionIconSet::MATCH_BIGGER, false, NULL));
}
-RenderViewHost* RenderViewHostTarget::GetRenderViewHost() const {
- return agent_host_->GetRenderViewHost();
+WebContents* WebContentsTarget::GetWebContents() const {
+ return GetAgentHost()->GetWebContents();
}
-int RenderViewHostTarget::GetTabId() const {
+int WebContentsTarget::GetTabId() const {
return tab_id_;
}
-std::string RenderViewHostTarget::GetExtensionId() const {
+std::string WebContentsTarget::GetExtensionId() const {
return extension_id_;
}
-void RenderViewHostTarget::Inspect(Profile* profile) const {
- RenderViewHost* rvh = GetRenderViewHost();
- if (!rvh)
+void WebContentsTarget::Inspect(Profile* profile) const {
+ WebContents* web_contents = GetWebContents();
+ if (!web_contents)
return;
- DevToolsWindow::OpenDevToolsWindow(rvh);
+ DevToolsWindow::OpenDevToolsWindow(web_contents);
}
-///////////////////////////////////////////////////////////////////////////////
+// WorkerTarget ----------------------------------------------------------------
class WorkerTarget : public DevToolsTargetImpl {
public:
- explicit WorkerTarget(const WorkerService::WorkerInfo& worker_info);
-
- // content::DevToolsTarget overrides:
- virtual bool Close() const OVERRIDE;
+ explicit WorkerTarget(scoped_refptr<DevToolsAgentHost> agent_host);
// DevToolsTargetImpl overrides:
- virtual void Inspect(Profile* profile) const OVERRIDE;
-
- private:
- int process_id_;
- int route_id_;
+ void Inspect(Profile* profile) const override;
};
-WorkerTarget::WorkerTarget(const WorkerService::WorkerInfo& worker) {
- agent_host_ =
- DevToolsAgentHost::GetForWorker(worker.process_id, worker.route_id);
- id_ = agent_host_->GetId();
- type_ = kTargetTypeWorker;
- title_ = base::UTF16ToUTF8(worker.name);
- description_ =
- base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle));
- url_ = worker.url;
-
- process_id_ = worker.process_id;
- route_id_ = worker.route_id;
-}
-
-static void TerminateWorker(int process_id, int route_id) {
- WorkerService::GetInstance()->TerminateWorker(process_id, route_id);
-}
-
-bool WorkerTarget::Close() const {
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&TerminateWorker, process_id_, route_id_));
- return true;
+WorkerTarget::WorkerTarget(scoped_refptr<DevToolsAgentHost> agent_host)
+ : DevToolsTargetImpl(agent_host) {
+ switch (agent_host->GetType()) {
+ case DevToolsAgentHost::TYPE_SHARED_WORKER:
+ set_type(kTargetTypeWorker);
+ break;
+ case DevToolsAgentHost::TYPE_SERVICE_WORKER:
+ set_type(kTargetTypeServiceWorker);
+ break;
+ default:
+ NOTREACHED();
+ }
}
void WorkerTarget::Inspect(Profile* profile) const {
- DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host_.get());
+ DevToolsWindow::OpenDevToolsWindowForWorker(profile, GetAgentHost());
}
} // namespace
+// DevToolsTargetImpl ----------------------------------------------------------
+
DevToolsTargetImpl::~DevToolsTargetImpl() {
}
-DevToolsTargetImpl::DevToolsTargetImpl() {
+DevToolsTargetImpl::DevToolsTargetImpl(
+ scoped_refptr<DevToolsAgentHost> agent_host)
+ : agent_host_(agent_host),
+ title_(agent_host->GetTitle()),
+ url_(agent_host->GetURL()) {
+}
+
+std::string DevToolsTargetImpl::GetParentId() const {
+ return parent_id_;
}
std::string DevToolsTargetImpl::GetId() const {
- return id_;
+ return agent_host_->GetId();
}
std::string DevToolsTargetImpl::GetType() const {
return description_;
}
-GURL DevToolsTargetImpl::GetUrl() const {
+GURL DevToolsTargetImpl::GetURL() const {
return url_;
}
-GURL DevToolsTargetImpl::GetFaviconUrl() const {
+GURL DevToolsTargetImpl::GetFaviconURL() const {
return favicon_url_;
}
}
bool DevToolsTargetImpl::Activate() const {
- return false;
+ return agent_host_->Activate();
}
bool DevToolsTargetImpl::Close() const {
- return false;
+ return agent_host_->Close();
}
int DevToolsTargetImpl::GetTabId() const {
return -1;
}
-RenderViewHost* DevToolsTargetImpl::GetRenderViewHost() const {
+WebContents* DevToolsTargetImpl::GetWebContents() const {
return NULL;
}
return std::string();
}
-void DevToolsTargetImpl::Inspect(Profile*) const {
+void DevToolsTargetImpl::Inspect(Profile* /*profile*/) const {
}
void DevToolsTargetImpl::Reload() const {
}
// static
-scoped_ptr<DevToolsTargetImpl> DevToolsTargetImpl::CreateForRenderViewHost(
- content::RenderViewHost* rvh, bool is_tab) {
- return scoped_ptr<DevToolsTargetImpl>(new RenderViewHostTarget(rvh, is_tab));
+scoped_ptr<DevToolsTargetImpl> DevToolsTargetImpl::CreateForWebContents(
+ content::WebContents* web_contents,
+ bool is_tab) {
+ return scoped_ptr<DevToolsTargetImpl>(
+ new WebContentsTarget(web_contents, is_tab));
}
// static
-scoped_ptr<DevToolsTargetImpl> DevToolsTargetImpl::CreateForWorker(
- const WorkerService::WorkerInfo& worker_info) {
- return scoped_ptr<DevToolsTargetImpl>(new WorkerTarget(worker_info));
-}
+void DevToolsTargetImpl::EnumerateAllTargets(Callback callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-// static
-DevToolsTargetImpl::List DevToolsTargetImpl::EnumerateRenderViewHostTargets() {
- std::set<RenderViewHost*> tab_rvhs;
+ std::set<WebContents*> tab_web_contents;
for (TabContentsIterator it; !it.done(); it.Next())
- tab_rvhs.insert(it->GetRenderViewHost());
+ tab_web_contents.insert(*it);
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DevToolsTargetImpl::List result;
- std::vector<RenderViewHost*> rvh_list =
- content::DevToolsAgentHost::GetValidRenderViewHosts();
- for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin();
- it != rvh_list.end(); ++it) {
- bool is_tab = tab_rvhs.find(*it) != tab_rvhs.end();
- result.push_back(new RenderViewHostTarget(*it, is_tab));
- }
- return result;
-}
-
-static void CreateWorkerTargets(
- const std::vector<WorkerService::WorkerInfo>& worker_info,
- DevToolsTargetImpl::Callback callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DevToolsTargetImpl::List result;
- for (size_t i = 0; i < worker_info.size(); ++i) {
- result.push_back(new WorkerTarget(worker_info[i]));
+ DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
+ for (DevToolsAgentHost::List::iterator it = agents.begin();
+ it != agents.end(); ++it) {
+ DevToolsAgentHost* agent_host = (*it).get();
+ switch (agent_host->GetType()) {
+ case DevToolsAgentHost::TYPE_WEB_CONTENTS:
+ if (WebContents* web_contents = agent_host->GetWebContents()) {
+ const bool is_tab =
+ tab_web_contents.find(web_contents) != tab_web_contents.end();
+ result.push_back(new WebContentsTarget(web_contents, is_tab));
+ }
+ break;
+ case DevToolsAgentHost::TYPE_SHARED_WORKER:
+ result.push_back(new WorkerTarget(agent_host));
+ break;
+ case DevToolsAgentHost::TYPE_SERVICE_WORKER:
+ result.push_back(new WorkerTarget(agent_host));
+ break;
+ default:
+ break;
+ }
}
- callback.Run(result);
-}
-
-// static
-void DevToolsTargetImpl::EnumerateWorkerTargets(Callback callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(&CreateWorkerTargets,
- WorkerService::GetInstance()->GetWorkers(),
- callback));
-}
-static void CollectAllTargets(
- DevToolsTargetImpl::Callback callback,
- const DevToolsTargetImpl::List& worker_targets) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DevToolsTargetImpl::List result =
- DevToolsTargetImpl::EnumerateRenderViewHostTargets();
- result.insert(result.begin(), worker_targets.begin(), worker_targets.end());
callback.Run(result);
}
-
-// static
-void DevToolsTargetImpl::EnumerateAllTargets(Callback callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- content::BrowserThread::PostTask(
- content::BrowserThread::IO,
- FROM_HERE,
- base::Bind(&DevToolsTargetImpl::EnumerateWorkerTargets,
- base::Bind(&CollectAllTargets, callback)));
-}