| 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;
|
| +}
|
|
|