Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6498)

Unified Diff: chrome/browser/extensions/api/debugger/debugger_api.cc

Issue 12377047: Add chrome.debugger.getTargets method to discover available debug targets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@targets
Patch Set: Removed flaky tests Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/debugger/debugger_api.cc
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc
index ade151aebb4bd9b1191396fa79051260e738cf51..a503a7564d0107a3f22526810e13874560c6b366 100644
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -34,6 +34,8 @@
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_client_host.h"
#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/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_process_host.h"
@@ -70,19 +72,19 @@ class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate {
// Creates an extension dev tools delegate and adds it to |infobar_service|.
// Returns a pointer to the delegate if it was successfully added.
static ExtensionDevToolsInfoBarDelegate* Create(
- InfoBarService* infobar_service,
- const std::string& client_name,
- ExtensionDevToolsClientHost* client_host);
+ WebContents* web_contents,
+ const std::string& client_name);
+
+ // Associates DevToolsClientHost with this infobar delegate.
+ void AttachClientHost(ExtensionDevToolsClientHost* client_host);
// Notifies infobar delegate that associated DevToolsClientHost will be
// destroyed.
void DiscardClientHost();
private:
- ExtensionDevToolsInfoBarDelegate(
- InfoBarService* infobar_service,
- const std::string& client_name,
- ExtensionDevToolsClientHost* client_host);
+ ExtensionDevToolsInfoBarDelegate(InfoBarService* infobar_service,
+ const std::string& client_name);
virtual ~ExtensionDevToolsInfoBarDelegate();
// ConfirmInfoBarDelegate:
@@ -102,10 +104,12 @@ class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate {
class ExtensionDevToolsClientHost : public DevToolsClientHost,
public content::NotificationObserver {
public:
- ExtensionDevToolsClientHost(WebContents* web_contents,
- const std::string& extension_id,
- const std::string& extension_name,
- const Debuggee& debuggee);
+ ExtensionDevToolsClientHost(
+ WebContents* web_contents,
+ const std::string& extension_id,
+ const std::string& extension_name,
+ const Debuggee& debuggee,
+ ExtensionDevToolsInfoBarDelegate* infobar_delegate);
virtual ~ExtensionDevToolsClientHost();
@@ -183,6 +187,70 @@ class AttachedClientHosts {
std::set<DevToolsClientHost*> client_hosts_;
};
+static extensions::ExtensionHost* GetExtensionBackgroundHost(
+ WebContents* web_contents) {
+ Profile* profile =
+ Profile::FromBrowserContext(web_contents->GetBrowserContext());
+ if (!profile)
+ return NULL;
+
+ extensions::ExtensionHost* extension_host =
+ extensions::ExtensionSystem::Get(profile)->process_manager()->
+ GetBackgroundHostForExtension(web_contents->GetURL().host());
+
+ if (extension_host && extension_host->host_contents() == web_contents)
+ return extension_host;
+
+ return NULL;
+}
+
+static const char kTargetIdField[] = "id";
+static const char kTargetTypeField[] = "type";
+static const char kTargetTitleField[] = "title";
+static const char kTargetAttachedField[] = "attached";
+static const char kTargetUrlField[] = "url";
+static const char kTargetFaviconUrlField[] = "faviconUrl";
+
+static const char kTargetTypePage[] = "page";
+static const char kTargetTypeBackgroundPage[] = "background_page";
+
+static base::Value* SerializePageInfo(RenderViewHost* rvh) {
+ WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
+ if (!web_contents)
+ return NULL;
+
+ DevToolsAgentHost* agent_host = DevToolsAgentHost::GetOrCreateFor(rvh);
+
+ base::DictionaryValue* dictionary = new base::DictionaryValue();
+
+ dictionary->SetString(kTargetIdField, agent_host->GetId());
+ dictionary->SetBoolean(kTargetAttachedField, agent_host->IsAttached());
+ dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec());
+
+ extensions::ExtensionHost* extension_host =
+ GetExtensionBackgroundHost(web_contents);
+ if (extension_host) {
+ // This RenderViewHost belongs to a background page.
+ dictionary->SetString(kTargetTypeField, kTargetTypeBackgroundPage);
+ dictionary->SetString(kTargetTitleField,
+ extension_host->extension()->name());
+ } else {
+ // This RenderViewHost belongs to a regular page.
+ dictionary->SetString(kTargetTypeField, kTargetTypePage);
+ dictionary->SetString(kTargetTitleField,
+ UTF16ToUTF8(net::EscapeForHTML(web_contents->GetTitle())));
+
+ content::NavigationController& controller = web_contents->GetController();
+ content::NavigationEntry* entry = controller.GetActiveEntry();
+ if (entry != NULL && entry->GetURL().is_valid()) {
+ dictionary->SetString(kTargetFaviconUrlField,
+ entry->GetFavicon().url.spec());
+ }
+ }
+
+ return dictionary;
+}
+
} // namespace
static void CopyDebuggee(Debuggee & dst, const Debuggee& src) {
@@ -190,17 +258,20 @@ static void CopyDebuggee(Debuggee & dst, const Debuggee& src) {
dst.tab_id.reset(new int(*src.tab_id));
if (src.extension_id)
dst.extension_id.reset(new std::string(*src.extension_id));
+ if (src.target_id)
+ dst.target_id.reset(new std::string(*src.target_id));
}
ExtensionDevToolsClientHost::ExtensionDevToolsClientHost(
WebContents* web_contents,
const std::string& extension_id,
const std::string& extension_name,
- const Debuggee& debuggee)
+ const Debuggee& debuggee,
+ ExtensionDevToolsInfoBarDelegate* infobar_delegate)
: web_contents_(web_contents),
extension_id_(extension_id),
last_request_id_(0),
- infobar_delegate_(NULL),
+ infobar_delegate_(infobar_delegate),
detach_reason_(OnDetach::REASON_TARGET_CLOSED) {
CopyDebuggee(debuggee_, debuggee);
@@ -217,16 +288,11 @@ ExtensionDevToolsClientHost::ExtensionDevToolsClientHost(
web_contents_->GetRenderViewHost()));
DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this);
- if (!CommandLine::ForCurrentProcess()->
- HasSwitch(switches::kSilentDebuggerExtensionAPI)) {
- InfoBarService* infobar_service =
- InfoBarService::FromWebContents(web_contents_);
- infobar_delegate_ = ExtensionDevToolsInfoBarDelegate::Create(
- infobar_service, extension_name, this);
- if (infobar_delegate_) {
- registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
- content::Source<InfoBarService>(infobar_service));
- }
+ if (infobar_delegate_) {
+ infobar_delegate_->AttachClientHost(this);
+ registrar_.Add(this,
+ chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
+ content::Source<InfoBarService>(infobar_delegate_->owner()));
}
}
@@ -237,10 +303,8 @@ ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() {
if (infobar_delegate_) {
infobar_delegate_->DiscardClientHost();
- InfoBarService* infobar_service =
- InfoBarService::FromWebContents(web_contents_);
- if (infobar_service)
- infobar_service->RemoveInfoBar(infobar_delegate_);
+ if (infobar_delegate_->owner())
+ infobar_delegate_->owner()->RemoveInfoBar(infobar_delegate_);
}
AttachedClientHosts::GetInstance()->Remove(this);
}
@@ -367,13 +431,20 @@ void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend(
// static
ExtensionDevToolsInfoBarDelegate* ExtensionDevToolsInfoBarDelegate::Create(
- InfoBarService* infobar_service,
- const std::string& client_name,
- ExtensionDevToolsClientHost* client_host) {
+ WebContents* web_contents,
+ const std::string& client_name) {
+ InfoBarService* infobar_service =
+ InfoBarService::FromWebContents(web_contents);
+ if (!infobar_service)
+ return NULL;
return static_cast<ExtensionDevToolsInfoBarDelegate*>(
infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
- new ExtensionDevToolsInfoBarDelegate(infobar_service, client_name,
- client_host))));
+ new ExtensionDevToolsInfoBarDelegate(infobar_service, client_name))));
+}
+
+void ExtensionDevToolsInfoBarDelegate::AttachClientHost(
+ ExtensionDevToolsClientHost* client_host) {
+ client_host_ = client_host;
}
void ExtensionDevToolsInfoBarDelegate::DiscardClientHost() {
@@ -382,11 +453,10 @@ void ExtensionDevToolsInfoBarDelegate::DiscardClientHost() {
ExtensionDevToolsInfoBarDelegate::ExtensionDevToolsInfoBarDelegate(
InfoBarService* infobar_service,
- const std::string& client_name,
- ExtensionDevToolsClientHost* client_host)
+ const std::string& client_name)
: ConfirmInfoBarDelegate(infobar_service),
client_name_(client_name),
- client_host_(client_host) {
+ client_host_(NULL) {
}
ExtensionDevToolsInfoBarDelegate::~ExtensionDevToolsInfoBarDelegate() {
@@ -427,64 +497,57 @@ DebuggerFunction::DebuggerFunction()
}
void DebuggerFunction::FormatErrorMessage(const std::string& format) {
- error_ = ErrorUtils::FormatErrorMessage(
- format,
- debuggee_.tab_id ?
- keys::kTabTargetType :
- keys::kExtensionTargetType,
- debuggee_.tab_id ?
- base::IntToString(*debuggee_.tab_id) :
- *debuggee_.extension_id);
+ if (debuggee_.tab_id)
+ error_ = ErrorUtils::FormatErrorMessage(
+ format, keys::kTabTargetType, base::IntToString(*debuggee_.tab_id));
+ else if (debuggee_.extension_id)
+ error_ = ErrorUtils::FormatErrorMessage(
+ format, keys::kBackgroundPageTargetType, *debuggee_.extension_id);
+ else
+ error_ = ErrorUtils::FormatErrorMessage(
+ format, keys::kOpaqueTargetType, *debuggee_.target_id);
}
bool DebuggerFunction::InitWebContents() {
- // Find the WebContents that contains this tab id.
- contents_ = NULL;
if (debuggee_.tab_id) {
WebContents* web_contents = NULL;
bool result = ExtensionTabUtil::GetTabById(
*debuggee_.tab_id, profile(), include_incognito(), NULL, NULL,
&web_contents, NULL);
- if (!result || !web_contents) {
- FormatErrorMessage(keys::kNoTargetError);
- return false;
+ if (result && web_contents) {
+ if (content::HasWebUIScheme(web_contents->GetURL())) {
+ error_ = ErrorUtils::FormatErrorMessage(
+ keys::kAttachToWebUIError,
+ web_contents->GetURL().scheme());
+ return false;
+ }
+ contents_ = web_contents;
}
- contents_ = web_contents;
-
- if (content::HasWebUIScheme(contents_->GetURL())) {
- error_ = ErrorUtils::FormatErrorMessage(
- keys::kAttachToWebUIError,
- contents_->GetURL().scheme());
- return false;
- }
-
- return true;
- }
-
- if (debuggee_.extension_id) {
- if (!CommandLine::ForCurrentProcess()->
- HasSwitch(switches::kSilentDebuggerExtensionAPI)) {
- error_ = ErrorUtils::FormatErrorMessage(
- keys::kSilentDebuggingRequired,
- switches::kSilentDebuggerExtensionAPI);
- return false;
- }
-
- extensions::ExtensionHost* host =
+ } else if (debuggee_.extension_id) {
+ extensions::ExtensionHost* extension_host =
extensions::ExtensionSystem::Get(profile())->process_manager()->
GetBackgroundHostForExtension(*debuggee_.extension_id);
- if (host) {
- contents_ = WebContents::FromRenderViewHost(host->render_view_host());
- if (contents_)
- return true;
+ if (extension_host) {
+ contents_ = WebContents::FromRenderViewHost(
+ extension_host->render_view_host());
+ }
+ } else if (debuggee_.target_id) {
+ DevToolsAgentHost* agent_host =
+ DevToolsAgentHost::GetForId(*debuggee_.target_id);
+ if (agent_host) {
+ contents_ = WebContents::FromRenderViewHost(
+ agent_host->GetRenderViewHost());
}
+ } else {
+ error_ = keys::kInvalidTargetError;
+ return false;
+ }
+ if (!contents_) {
FormatErrorMessage(keys::kNoTargetError);
return false;
}
-
- error_ = keys::kInvalidTargetError;
- return false;
+ return true;
}
bool DebuggerFunction::InitClientHost() {
@@ -530,10 +593,27 @@ bool DebuggerAttachFunction::RunImpl() {
return false;
}
+ ExtensionDevToolsInfoBarDelegate* infobar_delegate = NULL;
+
+ if (!CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kSilentDebuggerExtensionAPI)) {
+ // Do not attach to the target if for any reason the infobar cannot be shown
+ // for this WebContents instance.
+ infobar_delegate = ExtensionDevToolsInfoBarDelegate::Create(
+ contents_, GetExtension()->name());
+ if (!infobar_delegate) {
+ error_ = ErrorUtils::FormatErrorMessage(
+ keys::kSilentDebuggingRequired,
+ switches::kSilentDebuggerExtensionAPI);
+ return false;
+ }
+ }
+
new ExtensionDevToolsClientHost(contents_,
GetExtension()->id(),
GetExtension()->name(),
- debuggee_);
+ debuggee_,
+ infobar_delegate);
SendResponse(true);
return true;
}
@@ -589,3 +669,24 @@ void DebuggerSendCommandFunction::SendResponseBody(
results_ = SendCommand::Results::Create(result);
SendResponse(true);
}
+
+DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {}
+
+DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {}
+
+bool DebuggerGetTargetsFunction::RunImpl() {
+ base::ListValue* results_list = new ListValue();
+
+ std::vector<RenderViewHost*> rvh_list =
+ DevToolsAgentHost::GetValidRenderViewHosts();
+ for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin();
+ it != rvh_list.end(); ++it) {
+ base::Value* value = SerializePageInfo(*it);
+ if (value)
+ results_list->Append(value);
+ }
+
+ SetResult(results_list);
+ SendResponse(true);
+ return true;
+}
« no previous file with comments | « chrome/browser/extensions/api/debugger/debugger_api.h ('k') | chrome/browser/extensions/api/debugger/debugger_api_constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698