Commit e1133eb0 authored by vkuzkokov's avatar vkuzkokov Committed by Commit bot

DevTools: Added service workers to remote debugging targets

This one contains the required API changes to include service workers in remote debugging.
For now service workers will show up as "untitled" as they do not have a title to speak of.

Split off https://codereview.chromium.org/349033009/

BUG=389454
TBR= mnaganov@chromium.org (android_webview/native/aw_dev_tools_server.cc)

Review URL: https://codereview.chromium.org/459403002

Cr-Commit-Position: refs/heads/master@{#291676}
parent c9d27bad
......@@ -32,19 +32,33 @@ const char kFrontEndURL[] =
const char kSocketNameFormat[] = "webview_devtools_remote_%d";
const char kTargetTypePage[] = "page";
const char kTargetTypeServiceWorker[] = "service_worker";
const char kTargetTypeOther[] = "other";
std::string GetViewDescription(WebContents* web_contents);
class Target : public content::DevToolsTarget {
public:
explicit Target(WebContents* web_contents);
explicit Target(scoped_refptr<DevToolsAgentHost> agent_host);
virtual std::string GetId() const OVERRIDE { return id_; }
virtual std::string GetId() const OVERRIDE { return agent_host_->GetId(); }
virtual std::string GetParentId() const OVERRIDE { return std::string(); }
virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
virtual std::string GetTitle() const OVERRIDE { return title_; }
virtual std::string GetType() const OVERRIDE {
switch (agent_host_->GetType()) {
case DevToolsAgentHost::TYPE_WEB_CONTENTS:
return kTargetTypePage;
case DevToolsAgentHost::TYPE_SERVICE_WORKER:
return kTargetTypeServiceWorker;
default:
break;
}
return kTargetTypeOther;
}
virtual std::string GetTitle() const OVERRIDE {
return agent_host_->GetTitle();
}
virtual std::string GetDescription() const OVERRIDE { return description_; }
virtual GURL GetURL() const OVERRIDE { return url_; }
virtual GURL GetURL() const OVERRIDE { return agent_host_->GetURL(); }
virtual GURL GetFaviconURL() const OVERRIDE { return GURL(); }
virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
return last_activity_time_;
......@@ -55,26 +69,21 @@ class Target : public content::DevToolsTarget {
virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
return agent_host_;
}
virtual bool Activate() const OVERRIDE { return false; }
virtual bool Close() const OVERRIDE { return false; }
virtual bool Activate() const OVERRIDE { return agent_host_->Activate(); }
virtual bool Close() const OVERRIDE { return agent_host_->Close(); }
private:
scoped_refptr<DevToolsAgentHost> agent_host_;
std::string id_;
std::string title_;
std::string description_;
GURL url_;
base::TimeTicks last_activity_time_;
};
Target::Target(WebContents* web_contents) {
agent_host_ =
DevToolsAgentHost::GetOrCreateFor(web_contents);
id_ = agent_host_->GetId();
description_ = GetViewDescription(web_contents);
title_ = base::UTF16ToUTF8(web_contents->GetTitle());
url_ = web_contents->GetURL();
last_activity_time_ = web_contents->GetLastActiveTime();
Target::Target(scoped_refptr<DevToolsAgentHost> agent_host)
: agent_host_(agent_host) {
if (WebContents* web_contents = agent_host->GetWebContents()) {
description_ = GetViewDescription(web_contents);
last_activity_time_ = web_contents->GetLastActiveTime();
}
}
// Delegate implementation for the devtools http handler for WebView. A new
......@@ -106,10 +115,9 @@ class AwDevToolsServerDelegate : public content::DevToolsHttpHandlerDelegate {
virtual void EnumerateTargets(TargetCallback callback) OVERRIDE {
TargetList targets;
std::vector<WebContents*> wc_list =
DevToolsAgentHost::GetInspectableWebContents();
for (std::vector<WebContents*>::iterator it = wc_list.begin();
it != wc_list.end(); ++it) {
DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
for (DevToolsAgentHost::List::iterator it = agents.begin();
it != agents.end(); ++it) {
targets.push_back(new Target(*it));
}
callback.Run(targets);
......
......@@ -66,6 +66,7 @@ const char kFrontEndURL[] =
const char kTetheringSocketName[] = "chrome_devtools_tethering_%d_%d";
const char kTargetTypePage[] = "page";
const char kTargetTypeServiceWorker[] = "service_worker";
const char kTargetTypeOther[] = "other";
static GURL GetFaviconURLForContents(WebContents* web_contents) {
......@@ -76,6 +77,20 @@ static GURL GetFaviconURLForContents(WebContents* web_contents) {
return GURL();
}
static GURL GetFaviconURLForAgentHost(
scoped_refptr<DevToolsAgentHost> agent_host) {
if (WebContents* web_contents = agent_host->GetWebContents())
return GetFaviconURLForContents(web_contents);
return GURL();
}
static base::TimeTicks GetLastActiveTimeForAgentHost(
scoped_refptr<DevToolsAgentHost> agent_host) {
if (WebContents* web_contents = agent_host->GetWebContents())
return web_contents->GetLastActiveTime();
return base::TimeTicks();
}
bool AuthorizeSocketAccessWithDebugPermission(
const net::UnixDomainServerSocket::Credentials& credentials) {
JNIEnv* env = base::android::AttachCurrentThread();
......@@ -110,10 +125,17 @@ class TargetBase : public content::DevToolsTarget {
last_activity_time_(web_contents->GetLastActiveTime()) {
}
TargetBase(const base::string16& title, const GURL& url)
: title_(base::UTF16ToUTF8(title)),
url_(url)
{}
explicit TargetBase(scoped_refptr<DevToolsAgentHost> agent_host)
: title_(agent_host->GetTitle()),
url_(agent_host->GetURL()),
favicon_url_(GetFaviconURLForAgentHost(agent_host)),
last_activity_time_(GetLastActiveTimeForAgentHost(agent_host)) {
}
TargetBase(const std::string& title, const GURL& url)
: title_(title),
url_(url) {
}
private:
const std::string title_;
......@@ -140,7 +162,9 @@ class TabTarget : public TargetBase {
return base::IntToString(tab_id_);
}
virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
virtual std::string GetType() const OVERRIDE {
return kTargetTypePage;
}
virtual bool IsAttached() const OVERRIDE {
TabModel* model;
......@@ -195,7 +219,7 @@ class TabTarget : public TargetBase {
}
TabTarget(int tab_id, const base::string16& title, const GURL& url)
: TargetBase(title, url),
: TargetBase(base::UTF16ToUTF8(title), url),
tab_id_(tab_id) {
}
......@@ -220,9 +244,9 @@ class TabTarget : public TargetBase {
class NonTabTarget : public TargetBase {
public:
explicit NonTabTarget(WebContents* web_contents)
: TargetBase(web_contents),
agent_host_(DevToolsAgentHost::GetOrCreateFor(web_contents)) {
explicit NonTabTarget(scoped_refptr<DevToolsAgentHost> agent_host)
: TargetBase(agent_host),
agent_host_(agent_host) {
}
// content::DevToolsTarget implementation:
......@@ -231,10 +255,18 @@ class NonTabTarget : public TargetBase {
}
virtual std::string GetType() const OVERRIDE {
if (TabModelList::begin() == TabModelList::end()) {
// If there are no tab models we must be running in ChromeShell.
// Return the 'page' target type for backwards compatibility.
return kTargetTypePage;
switch (agent_host_->GetType()) {
case DevToolsAgentHost::TYPE_WEB_CONTENTS:
if (TabModelList::begin() == TabModelList::end()) {
// If there are no tab models we must be running in ChromeShell.
// Return the 'page' target type for backwards compatibility.
return kTargetTypePage;
}
break;
case DevToolsAgentHost::TYPE_SERVICE_WORKER:
return kTargetTypeServiceWorker;
default:
break;
}
return kTargetTypeOther;
}
......@@ -248,19 +280,11 @@ class NonTabTarget : public TargetBase {
}
virtual bool Activate() const OVERRIDE {
WebContents* web_contents = agent_host_->GetWebContents();
if (!web_contents)
return false;
web_contents->GetDelegate()->ActivateContents(web_contents);
return true;
return agent_host_->Activate();
}
virtual bool Close() const OVERRIDE {
WebContents* web_contents = agent_host_->GetWebContents();
if (!web_contents)
return false;
web_contents->GetRenderViewHost()->ClosePage();
return true;
return agent_host_->Close();
}
private:
......@@ -351,13 +375,14 @@ class DevToolsServerDelegate : public content::DevToolsHttpHandlerDelegate {
}
// Add targets for WebContents not associated with any tabs.
std::vector<WebContents*> wc_list =
DevToolsAgentHost::GetInspectableWebContents();
for (std::vector<WebContents*>::iterator it = wc_list.begin();
it != wc_list.end();
++it) {
if (tab_web_contents.find(*it) != tab_web_contents.end())
continue;
DevToolsAgentHost::List agents =
DevToolsAgentHost::GetOrCreateAll();
for (DevToolsAgentHost::List::iterator it = agents.begin();
it != agents.end(); ++it) {
if (WebContents* web_contents = (*it)->GetWebContents()) {
if (tab_web_contents.find(web_contents) != tab_web_contents.end())
continue;
}
targets.push_back(new NonTabTarget(*it));
}
......
......@@ -40,6 +40,7 @@ const char kTargetTypeWorker[] = "worker";
const char kTargetTypeWebView[] = "webview";
const char kTargetTypeIFrame[] = "iframe";
const char kTargetTypeOther[] = "other";
const char kTargetTypeServiceWorker[] = "service_worker";
// WebContentsTarget --------------------------------------------------------
......@@ -48,8 +49,6 @@ class WebContentsTarget : public DevToolsTargetImpl {
WebContentsTarget(WebContents* web_contents, bool is_tab);
// DevToolsTargetImpl overrides:
virtual bool Activate() const OVERRIDE;
virtual bool Close() const OVERRIDE;
virtual WebContents* GetWebContents() const OVERRIDE;
virtual int GetTabId() const OVERRIDE;
virtual std::string GetExtensionId() const OVERRIDE;
......@@ -77,8 +76,6 @@ WebContentsTarget::WebContentsTarget(WebContents* web_contents, bool is_tab)
return;
}
set_title(base::UTF16ToUTF8(web_contents->GetTitle()));
set_url(web_contents->GetURL());
content::NavigationController& controller = web_contents->GetController();
content::NavigationEntry* entry = controller.GetActiveEntry();
if (entry != NULL && entry->GetURL().is_valid())
......@@ -130,22 +127,6 @@ WebContentsTarget::WebContentsTarget(WebContents* web_contents, bool is_tab)
ExtensionIconSet::MATCH_BIGGER, false, NULL));
}
bool WebContentsTarget::Activate() const {
WebContents* web_contents = GetWebContents();
if (!web_contents)
return false;
web_contents->GetDelegate()->ActivateContents(web_contents);
return true;
}
bool WebContentsTarget::Close() const {
WebContents* web_contents = GetWebContents();
if (!web_contents)
return false;
web_contents->GetRenderViewHost()->ClosePage();
return true;
}
WebContents* WebContentsTarget::GetWebContents() const {
return GetAgentHost()->GetWebContents();
}
......@@ -171,38 +152,35 @@ 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 std::string GetType() const OVERRIDE;
virtual void Inspect(Profile* profile) const OVERRIDE;
private:
int process_id_;
int route_id_;
};
WorkerTarget::WorkerTarget(const WorkerService::WorkerInfo& worker)
: DevToolsTargetImpl(DevToolsAgentHost::GetForWorker(worker.process_id,
worker.route_id)) {
set_type(kTargetTypeWorker);
set_title(base::UTF16ToUTF8(worker.name));
set_description(base::StringPrintf("Worker pid:%d",
base::GetProcId(worker.handle)));
set_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);
WorkerTarget::WorkerTarget(
scoped_refptr<DevToolsAgentHost> agent_host)
: DevToolsTargetImpl(agent_host) {
}
bool WorkerTarget::Close() const {
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
base::Bind(&TerminateWorker, process_id_, route_id_));
return true;
std::string WorkerTarget::GetType() const {
switch (GetAgentHost()->GetType()) {
case DevToolsAgentHost::TYPE_SHARED_WORKER:
return kTargetTypeWorker;
case DevToolsAgentHost::TYPE_SERVICE_WORKER:
return kTargetTypeServiceWorker;
default:
break;
}
return kTargetTypeOther;
}
void WorkerTarget::Inspect(Profile* profile) const {
......@@ -218,7 +196,9 @@ DevToolsTargetImpl::~DevToolsTargetImpl() {
DevToolsTargetImpl::DevToolsTargetImpl(
scoped_refptr<DevToolsAgentHost> agent_host)
: agent_host_(agent_host) {
: agent_host_(agent_host),
title_(agent_host->GetTitle()),
url_(agent_host->GetURL()) {
}
std::string DevToolsTargetImpl::GetParentId() const {
......@@ -263,11 +243,11 @@ bool DevToolsTargetImpl::IsAttached() const {
}
bool DevToolsTargetImpl::Activate() const {
return false;
return agent_host_->Activate();
}
bool DevToolsTargetImpl::Close() const {
return false;
return agent_host_->Close();
}
int DevToolsTargetImpl::GetTabId() const {
......@@ -304,13 +284,14 @@ DevToolsTargetImpl::List DevToolsTargetImpl::EnumerateWebContentsTargets() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DevToolsTargetImpl::List result;
std::vector<WebContents*> wc_list =
content::DevToolsAgentHost::GetInspectableWebContents();
for (std::vector<WebContents*>::iterator it = wc_list.begin();
it != wc_list.end();
++it) {
bool is_tab = tab_web_contents.find(*it) != tab_web_contents.end();
result.push_back(new WebContentsTarget(*it, is_tab));
DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
for (DevToolsAgentHost::List::iterator it = agents.begin();
it != agents.end(); ++it) {
if (WebContents* web_contents = (*it)->GetWebContents()) {
bool is_tab =
tab_web_contents.find(web_contents) != tab_web_contents.end();
result.push_back(new WebContentsTarget(web_contents, is_tab));
}
}
return result;
}
......@@ -343,7 +324,14 @@ static void CollectAllTargets(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DevToolsTargetImpl::List result =
DevToolsTargetImpl::EnumerateWebContentsTargets();
result.insert(result.begin(), worker_targets.begin(), worker_targets.end());
result.insert(result.end(), worker_targets.begin(), worker_targets.end());
DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
for (DevToolsAgentHost::List::iterator it = agents.begin();
it != agents.end(); ++it) {
if ((*it)->GetType() == DevToolsAgentHost::TYPE_SERVICE_WORKER)
result.push_back(new WorkerTarget(*it));
}
callback.Run(result);
}
......
......@@ -11,6 +11,7 @@
#include "base/guid.h"
#include "base/lazy_instance.h"
#include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/embedded_worker_devtools_manager.h"
#include "content/browser/devtools/forwarding_agent_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_manager_delegate.h"
......@@ -27,6 +28,19 @@ base::LazyInstance<AgentStateCallbacks>::Leaky g_callbacks =
LAZY_INSTANCE_INITIALIZER;
} // namespace
// static
DevToolsAgentHost::List DevToolsAgentHost::GetOrCreateAll() {
List result = EmbeddedWorkerDevToolsManager::GetInstance()
->GetOrCreateAllAgentHosts();
std::vector<WebContents*> wc_list =
DevToolsAgentHostImpl::GetInspectableWebContents();
for (std::vector<WebContents*>::iterator it = wc_list.begin();
it != wc_list.end(); ++it) {
result.push_back(GetOrCreateFor(*it));
}
return result;
}
DevToolsAgentHostImpl::DevToolsAgentHostImpl()
: id_(base::GenerateGUID()),
client_(NULL) {
......@@ -39,7 +53,7 @@ DevToolsAgentHostImpl::~DevToolsAgentHostImpl() {
g_instances.Get().erase(g_instances.Get().find(id_));
}
//static
// static
scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForId(
const std::string& id) {
if (g_instances == NULL)
......
......@@ -22,6 +22,9 @@ class BrowserContext;
// Describes interface for managing devtools agents from the browser process.
class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
public:
// Returns a list of all existing WebContents that can be debugged.
static std::vector<WebContents*> GetInspectableWebContents();
// Informs the hosted agent that a client host has attached.
virtual void Attach() = 0;
......
......@@ -4,6 +4,7 @@
#include "content/browser/devtools/embedded_worker_devtools_agent_host.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
......@@ -63,6 +64,14 @@ bool EmbeddedWorkerDevToolsAgentHost::IsWorker() const {
return true;
}
DevToolsAgentHost::Type EmbeddedWorkerDevToolsAgentHost::GetType() {
return shared_worker_ ? TYPE_SHARED_WORKER : TYPE_SERVICE_WORKER;
}
std::string EmbeddedWorkerDevToolsAgentHost::GetTitle() {
return shared_worker_ ? base::UTF16ToUTF8(shared_worker_->name()) : "";
}
GURL EmbeddedWorkerDevToolsAgentHost::GetURL() {
if (shared_worker_)
return shared_worker_->url();
......@@ -71,6 +80,10 @@ GURL EmbeddedWorkerDevToolsAgentHost::GetURL() {
return GURL();
}
bool EmbeddedWorkerDevToolsAgentHost::Activate() {
return false;
}
bool EmbeddedWorkerDevToolsAgentHost::Close() {
if (shared_worker_) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
......@@ -180,6 +193,10 @@ bool EmbeddedWorkerDevToolsAgentHost::Matches(
return service_worker_ && service_worker_->Matches(other);
}
bool EmbeddedWorkerDevToolsAgentHost::IsTerminated() {
return state_ == WORKER_TERMINATED;
}
EmbeddedWorkerDevToolsAgentHost::~EmbeddedWorkerDevToolsAgentHost() {
DCHECK_EQ(WORKER_TERMINATED, state_);
EmbeddedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(
......
......@@ -29,6 +29,11 @@ class EmbeddedWorkerDevToolsAgentHost : public IPCDevToolsAgentHost,
// DevToolsAgentHost override.
virtual bool IsWorker() const OVERRIDE;
virtual Type GetType() OVERRIDE;
virtual std::string GetTitle() OVERRIDE;
virtual GURL GetURL() OVERRIDE;
virtual bool Activate() OVERRIDE;
virtual bool Close() OVERRIDE;
// IPCDevToolsAgentHost implementation.
virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE;
......@@ -45,9 +50,7 @@ class EmbeddedWorkerDevToolsAgentHost : public IPCDevToolsAgentHost,
void WorkerDestroyed();
bool Matches(const SharedWorkerInstance& other);
bool Matches(const ServiceWorkerIdentifier& other);
virtual GURL GetURL();
virtual bool Close();
bool IsTerminated();
private:
friend class EmbeddedWorkerDevToolsManagerTest;
......
......@@ -183,6 +183,18 @@ EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerAgentHost(
return it;
}
DevToolsAgentHost::List
EmbeddedWorkerDevToolsManager::GetOrCreateAllAgentHosts() {
DevToolsAgentHost::List result;
EmbeddedWorkerDevToolsManager* instance = GetInstance();
for (AgentHostMap::iterator it = instance->workers_.begin();
it != instance->workers_.end(); ++it) {
if (!it->second->IsTerminated())
result.push_back(it->second);
}
return result;
}
void EmbeddedWorkerDevToolsManager::WorkerRestarted(
const WorkerId& id,
const AgentHostMap::iterator& it) {
......
......@@ -18,6 +18,7 @@
namespace content {
class DevToolsAgentHost;
class DevToolsAgentHostImpl;
class EmbeddedWorkerDevToolsAgentHost;
class ServiceWorkerContextCore;
......@@ -59,6 +60,8 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
DevToolsAgentHostImpl* GetDevToolsAgentHostForWorker(int worker_process_id,
int worker_route_id);
std::vector<scoped_refptr<DevToolsAgentHost> > GetOrCreateAllAgentHosts();
// Returns true when the worker must be paused on start because a DevTool
// window for the same former SharedWorkerInstance is still opened.
bool SharedWorkerCreated(int worker_process_id,
......
......@@ -37,4 +37,24 @@ void ForwardingAgentHost::DispatchProtocolMessage(
delegate_->SendMessageToBackend(message);
}
DevToolsAgentHost::Type ForwardingAgentHost::GetType() {
return TYPE_EXTERNAL;
}
std::string ForwardingAgentHost::GetTitle() {
return "";
}
GURL ForwardingAgentHost::GetURL() {
return GURL();
}
bool ForwardingAgentHost::Activate() {
return false;
}
bool ForwardingAgentHost::Close() {
return false;
}
} // content
......@@ -31,6 +31,13 @@ class ForwardingAgentHost
virtual void Detach() OVERRIDE;
virtual void DispatchProtocolMessage(const std::string& message) OVERRIDE;
// DevToolsAgentHost implementation
virtual Type GetType() OVERRIDE;
virtual std::string GetTitle() OVERRIDE;
virtual GURL GetURL() OVERRIDE;
virtual bool Activate() OVERRIDE;
virtual bool Close() OVERRIDE;
scoped_ptr<DevToolsExternalAgentProxyDelegate> delegate_;
};
......
......@@ -6,6 +6,7 @@
#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/devtools_power_handler.h"
......@@ -24,6 +25,7 @@
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_iterator.h"
#include "content/public/browser/web_contents_delegate.h"
#if defined(OS_ANDROID)
#include "content/browser/power_save_blocker_impl.h"
......@@ -72,7 +74,7 @@ bool DevToolsAgentHost::IsDebuggerAttached(WebContents* web_contents) {
}
//static
std::vector<WebContents*> DevToolsAgentHost::GetInspectableWebContents() {
std::vector<WebContents*> DevToolsAgentHostImpl::GetInspectableWebContents() {
std::set<WebContents*> set;
scoped_ptr<RenderWidgetHostIterator> widgets(
RenderWidgetHost::GetRenderWidgetHosts());
......@@ -377,6 +379,39 @@ void RenderViewDevToolsAgentHost::ConnectWebContents(WebContents* wc) {
ConnectRenderViewHost(wc->GetRenderViewHost());
}
DevToolsAgentHost::Type RenderViewDevToolsAgentHost::GetType() {
return TYPE_WEB_CONTENTS;
}
std::string RenderViewDevToolsAgentHost::GetTitle() {
if (WebContents* web_contents = GetWebContents())
return base::UTF16ToUTF8(web_contents->GetTitle());
return "";
}
GURL RenderViewDevToolsAgentHost::GetURL() {
if (WebContents* web_contents = GetWebContents())
return web_contents->GetVisibleURL();
return render_view_host_ ?
render_view_host_->GetMainFrame()->GetLastCommittedURL() : GURL();
}
bool RenderViewDevToolsAgentHost::Activate() {
if (render_view_host_) {
render_view_host_->GetDelegate()->Activate();
return true;
}
return false;
}
bool RenderViewDevToolsAgentHost::Close() {
if (render_view_host_) {
render_view_host_->ClosePage();
return true;
}
return false;
}
void RenderViewDevToolsAgentHost::ConnectRenderViewHost(RenderViewHost* rvh) {
SetRenderViewHost(rvh);
if (IsAttached())
......
......@@ -49,6 +49,11 @@ class CONTENT_EXPORT RenderViewDevToolsAgentHost
virtual void DisconnectWebContents() OVERRIDE;
virtual void ConnectWebContents(WebContents* web_contents) OVERRIDE;
virtual WebContents* GetWebContents() OVERRIDE;
virtual Type GetType() OVERRIDE;
virtual std::string GetTitle() OVERRIDE;
virtual GURL GetURL() OVERRIDE;
virtual bool Activate() OVERRIDE;
virtual bool Close() OVERRIDE;
private:
friend class DevToolsAgentHost;
......
......@@ -13,6 +13,7 @@
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/devtools_agent_host_client.h"
#include "url/gurl.h"
namespace content {
......@@ -23,6 +24,20 @@ class WebContents;
class CONTENT_EXPORT DevToolsAgentHost
: public base::RefCounted<DevToolsAgentHost> {
public:
enum Type {
// Agent host associated with WebContents.
TYPE_WEB_CONTENTS,
// Agent host associated with shared worker.
TYPE_SHARED_WORKER,
// Agent host associated with service worker.
TYPE_SERVICE_WORKER,
// Agent host associated with DevToolsExternalAgentProxyDelegate.
TYPE_EXTERNAL,
};
// Returns DevToolsAgentHost with a given |id| or NULL of it does not exist.
static scoped_refptr<DevToolsAgentHost> GetForId(const std::string& id);
......@@ -48,8 +63,10 @@ class CONTENT_EXPORT DevToolsAgentHost
static bool IsDebuggerAttached(WebContents* web_contents);
// Returns a list of all existing WebContents that can be debugged.
static std::vector<WebContents*> GetInspectableWebContents();
typedef std::vector<scoped_refptr<DevToolsAgentHost> > List;
// Returns all possible DevToolsAgentHosts.
static List GetOrCreateAll();
// Client attaches to this agent host to start debugging it.
virtual void AttachClient(DevToolsAgentHostClient* client) = 0;
......@@ -82,6 +99,21 @@ class CONTENT_EXPORT DevToolsAgentHost
// Returns true if DevToolsAgentHost is for worker.
virtual bool IsWorker() const = 0;
// Returns agent host type.
virtual Type GetType() = 0;
// Returns agent host title.
virtual std::string GetTitle() = 0;
// Returns url associated with agent host.
virtual GURL GetURL() = 0;
// Activates agent host. Returns false if the operation failed.
virtual bool Activate() = 0;
// Closes agent host. Returns false if the operation failed.
virtual bool Close() = 0;
// Terminates all debugging sessions and detaches all clients.
static void DetachAllClients();
......
......@@ -43,6 +43,8 @@ const char kFrontEndURL[] =
"http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
#endif
const char kTargetTypePage[] = "page";
const char kTargetTypeServiceWorker[] = "service_worker";
const char kTargetTypeOther[] = "other";
net::StreamListenSocketFactory* CreateSocketFactory() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
......@@ -76,14 +78,26 @@ net::StreamListenSocketFactory* CreateSocketFactory() {
class Target : public content::DevToolsTarget {
public:
explicit Target(WebContents* web_contents);
explicit Target(scoped_refptr<DevToolsAgentHost> agent_host);
virtual std::string GetId() const OVERRIDE { return id_; }
virtual std::string GetId() const OVERRIDE { return agent_host_->GetId(); }
virtual std::string GetParentId() const OVERRIDE { return std::string(); }
virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
virtual std::string GetTitle() const OVERRIDE { return title_; }
virtual std::string GetType() const OVERRIDE {
switch (agent_host_->GetType()) {
case DevToolsAgentHost::TYPE_WEB_CONTENTS:
return kTargetTypePage;
case DevToolsAgentHost::TYPE_SERVICE_WORKER:
return kTargetTypeServiceWorker;
default:
break;
}
return kTargetTypeOther;
}
virtual std::string GetTitle() const OVERRIDE {
return agent_host_->GetTitle();
}
virtual std::string GetDescription() const OVERRIDE { return std::string(); }
virtual GURL GetURL() const OVERRIDE { return url_; }
virtual GURL GetURL() const OVERRIDE { return agent_host_->GetURL(); }
virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
return last_activity_time_;
......@@ -99,39 +113,27 @@ class Target : public content::DevToolsTarget {
private:
scoped_refptr<DevToolsAgentHost> agent_host_;
std::string id_;
std::string title_;
GURL url_;
GURL favicon_url_;
base::TimeTicks last_activity_time_;
};
Target::Target(WebContents* web_contents) {
agent_host_ = DevToolsAgentHost::GetOrCreateFor(web_contents);
id_ = agent_host_->GetId();
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->GetLastActiveTime();
Target::Target(scoped_refptr<DevToolsAgentHost> agent_host)
: agent_host_(agent_host) {
if (WebContents* web_contents = agent_host_->GetWebContents()) {
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->GetLastActiveTime();
}
}
bool Target::Activate() const {
WebContents* web_contents = agent_host_->GetWebContents();
if (!web_contents)
return false;
web_contents->GetDelegate()->ActivateContents(web_contents);
return true;
return agent_host_->Activate();
}
bool Target::Close() const {
WebContents* web_contents = agent_host_->GetWebContents();
if (!web_contents)
return false;
web_contents->GetRenderViewHost()->ClosePage();
return true;
return agent_host_->Close();
}
} // namespace
......@@ -189,16 +191,16 @@ ShellDevToolsDelegate::CreateNewTarget(const GURL& url) {
NULL,
MSG_ROUTING_NONE,
gfx::Size());
return scoped_ptr<DevToolsTarget>(new Target(shell->web_contents()));
return scoped_ptr<DevToolsTarget>(
new Target(DevToolsAgentHost::GetOrCreateFor(shell->web_contents())));
}
void ShellDevToolsDelegate::EnumerateTargets(TargetCallback callback) {
TargetList targets;
std::vector<WebContents*> wc_list =
content::DevToolsAgentHost::GetInspectableWebContents();
for (std::vector<WebContents*>::iterator it = wc_list.begin();
it != wc_list.end();
++it) {
content::DevToolsAgentHost::List agents =
content::DevToolsAgentHost::GetOrCreateAll();
for (content::DevToolsAgentHost::List::iterator it = agents.begin();
it != agents.end(); ++it) {
targets.push_back(new Target(*it));
}
callback.Run(targets);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment