Chromium Code Reviews| 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 66a2b2898ad53a001de61ecbb5944351f1c2cb31..5874a71b3d71cb86b99092d5686391dff9f47bcc 100644 |
| --- a/chrome/browser/extensions/api/debugger/debugger_api.cc |
| +++ b/chrome/browser/extensions/api/debugger/debugger_api.cc |
| @@ -20,6 +20,7 @@ |
| #include "chrome/browser/api/infobars/infobar_service.h" |
| #include "chrome/browser/extensions/api/debugger/debugger_api_constants.h" |
| #include "chrome/browser/extensions/event_router.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/infobars/infobar.h" |
| @@ -33,7 +34,9 @@ |
| #include "content/public/browser/devtools_manager.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_source.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.h" |
| #include "content/public/common/content_client.h" |
| #include "content/public/common/url_constants.h" |
| @@ -45,6 +48,9 @@ |
| using content::DevToolsAgentHost; |
| using content::DevToolsClientHost; |
| using content::DevToolsManager; |
| +using content::RenderProcessHost; |
| +using content::RenderViewHost; |
| +using content::RenderWidgetHost; |
| using content::WebContents; |
| using extensions::api::debugger::Debuggee; |
| using extensions::ErrorUtils; |
| @@ -98,7 +104,8 @@ class ExtensionDevToolsClientHost : public DevToolsClientHost, |
| ExtensionDevToolsClientHost(WebContents* web_contents, |
| const std::string& extension_id, |
| const std::string& extension_name, |
| - int tab_id); |
| + int debuggee_tab_id, |
| + const std::string& debuggee_extension_id); |
| virtual ~ExtensionDevToolsClientHost(); |
| @@ -127,7 +134,7 @@ class ExtensionDevToolsClientHost : public DevToolsClientHost, |
| WebContents* web_contents_; |
| std::string extension_id_; |
| - int tab_id_; |
| + Debuggee debuggee_; |
| content::NotificationRegistrar registrar_; |
| int last_request_id_; |
| typedef std::map<int, scoped_refptr<DebuggerSendCommandFunction> > |
| @@ -182,13 +189,18 @@ ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
| WebContents* web_contents, |
| const std::string& extension_id, |
| const std::string& extension_name, |
| - int tab_id) |
| + int debuggee_tab_id, |
| + const std::string& debuggee_extension_id) |
| : web_contents_(web_contents), |
| extension_id_(extension_id), |
| - tab_id_(tab_id), |
| last_request_id_(0), |
| infobar_delegate_(NULL), |
| detach_reason_(OnDetach::REASON_TARGET_CLOSED) { |
| + if (debuggee_tab_id) |
| + debuggee_.tab_id.reset(new int(debuggee_tab_id)); |
| + else |
| + debuggee_.extension_id.reset(new std::string(debuggee_extension_id)); |
| + |
| AttachedClientHosts::GetInstance()->Add(this); |
| // Detach from debugger when extension unloads. |
| @@ -204,12 +216,13 @@ ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
| 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_service) { |
| + 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)); |
| + } |
| } |
| } |
| @@ -277,9 +290,7 @@ void ExtensionDevToolsClientHost::SendDetachedEvent() { |
| Profile::FromBrowserContext(web_contents_->GetBrowserContext()); |
| if (profile != NULL && |
| extensions::ExtensionSystem::Get(profile)->event_router()) { |
| - Debuggee debuggee; |
| - debuggee.tab_id = tab_id_; |
| - scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee, |
| + scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee_, |
| detach_reason_)); |
| scoped_ptr<extensions::Event> event(new extensions::Event( |
| keys::kOnDetach, args.Pass())); |
| @@ -329,15 +340,12 @@ void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( |
| if (!dictionary->GetString("method", &method_name)) |
| return; |
| - Debuggee debuggee; |
| - debuggee.tab_id = tab_id_; |
| - |
| OnEvent::Params params; |
| DictionaryValue* params_value; |
| if (dictionary->GetDictionary("params", ¶ms_value)) |
| params.additional_properties.Swap(params_value); |
| - scoped_ptr<ListValue> args(OnEvent::Create(debuggee, method_name, params)); |
| + scoped_ptr<ListValue> args(OnEvent::Create(debuggee_, method_name, params)); |
| scoped_ptr<extensions::Event> event(new extensions::Event( |
| keys::kOnEvent, args.Pass())); |
| event->restrict_to_profile = profile; |
| @@ -411,32 +419,102 @@ bool ExtensionDevToolsInfoBarDelegate::Cancel() { |
| DebuggerFunction::DebuggerFunction() |
| : contents_(0), |
| - tab_id_(0), |
| + debuggee_tab_id_(0), |
| client_host_(0) { |
| } |
| +std::string DebuggerFunction::GetTargetTypeString() { |
|
pfeldman
2013/02/20 10:01:05
You only use these two to report the error. You co
Vladislav Kaznacheev
2013/02/20 12:02:26
Done.
|
| + if (debuggee_tab_id_) |
| + return keys::kTabTargetType; |
| + else |
| + return keys::kExtensionTargetType; |
| +} |
| + |
| +std::string DebuggerFunction::GetTargetIdString() { |
| + if (debuggee_tab_id_) |
| + return base::IntToString(debuggee_tab_id_); |
| + else |
| + return debuggee_extension_id_; |
| +} |
| + |
| +WebContents* FindWebContentsForExtension( |
|
pfeldman
2013/02/20 10:01:05
static
Vladislav Kaznacheev
2013/02/20 12:02:26
Done.
|
| + const extensions::Extension* extension) { |
| + for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); |
|
pfeldman
2013/02/20 10:01:05
Ok, this is the 3rd time it is used for inspector.
Vladislav Kaznacheev
2013/02/20 12:02:26
Filed a separate bug for that: https://code.google
|
| + !it.IsAtEnd(); it.Advance()) { |
| + RenderProcessHost* render_process_host = it.GetCurrentValue(); |
| + DCHECK(render_process_host); |
| + |
| + // Ignore processes that don't have a connection, such as crashed tabs. |
| + if (!render_process_host->HasConnection()) |
| + continue; |
| + |
| + 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* rvh = |
| + RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); |
| + |
| + WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
| + if (web_contents) { |
| + GURL url = web_contents->GetURL(); |
| + if (url.host() == extension->id()) { |
| + return web_contents; |
| + } |
| + } |
| + } |
| + } |
| + return NULL; |
| +} |
| + |
| bool DebuggerFunction::InitWebContents() { |
| // Find the WebContents that contains this tab id. |
| contents_ = NULL; |
| - WebContents* web_contents = NULL; |
| - bool result = ExtensionTabUtil::GetTabById( |
| - tab_id_, profile(), include_incognito(), NULL, NULL, &web_contents, NULL); |
| - if (!result || !web_contents) { |
| - error_ = ErrorUtils::FormatErrorMessage( |
| - keys::kNoTabError, |
| - base::IntToString(tab_id_)); |
| - return false; |
| + if (debuggee_tab_id_) { |
| + WebContents* web_contents = NULL; |
|
pfeldman
2013/02/20 10:01:05
This could be extracted as FindWebContentsForTabId
Vladislav Kaznacheev
2013/02/20 12:02:26
As discussed offline it does not really provide an
|
| + bool result = ExtensionTabUtil::GetTabById(debuggee_tab_id_, profile(), |
| + include_incognito(), NULL, NULL, &web_contents, NULL); |
| + if (!result || !web_contents) { |
| + error_ = ErrorUtils::FormatErrorMessage( |
| + keys::kNoTargetError, |
| + GetTargetTypeString(), |
| + GetTargetIdString()); |
| + return false; |
| + } |
| + contents_ = web_contents; |
| + |
| + if (content::HasWebUIScheme(contents_->GetURL())) { |
| + error_ = ErrorUtils::FormatErrorMessage( |
| + keys::kAttachToWebUIError, |
| + contents_->GetURL().scheme()); |
| + return false; |
| + } |
| + |
| + return true; |
| } |
| - contents_ = web_contents; |
| - if (content::HasWebUIScheme(contents_->GetURL())) { |
| + if (debuggee_extension_id_.size()) { |
| + const extensions::Extension* extension = profile()->GetExtensionService()-> |
| + extensions()->GetByID(debuggee_extension_id_); |
| + if (extension) { |
| + contents_ = FindWebContentsForExtension(extension); |
| + if (contents_) |
| + return true; |
| + } |
| + |
| error_ = ErrorUtils::FormatErrorMessage( |
| - keys::kAttachToWebUIError, |
| - contents_->GetURL().scheme()); |
| + keys::kNoTargetError, |
| + GetTargetTypeString(), |
| + GetTargetIdString()); |
| return false; |
| } |
| - return true; |
| + error_ = keys::kInvalidTargetError; |
| + return false; |
| } |
| bool DebuggerFunction::InitClientHost() { |
| @@ -451,7 +529,8 @@ bool DebuggerFunction::InitClientHost() { |
| GetExtension()->id())) { |
| error_ = ErrorUtils::FormatErrorMessage( |
| keys::kNotAttachedError, |
| - base::IntToString(tab_id_)); |
| + GetTargetTypeString(), |
| + GetTargetIdString()); |
| return false; |
| } |
| return true; |
| @@ -465,7 +544,10 @@ bool DebuggerAttachFunction::RunImpl() { |
| scoped_ptr<Attach::Params> params(Attach::Params::Create(*args_)); |
| EXTENSION_FUNCTION_VALIDATE(params.get()); |
| - tab_id_ = params->target.tab_id; |
| + if (params->target.tab_id) |
| + debuggee_tab_id_ = *params->target.tab_id; |
| + if (params->target.extension_id) |
| + debuggee_extension_id_ = *params->target.extension_id; |
| if (!InitWebContents()) |
| return false; |
| @@ -485,14 +567,16 @@ bool DebuggerAttachFunction::RunImpl() { |
| if (client_host != NULL) { |
| error_ = ErrorUtils::FormatErrorMessage( |
| keys::kAlreadyAttachedError, |
| - base::IntToString(tab_id_)); |
| + GetTargetTypeString(), |
| + GetTargetIdString()); |
| return false; |
| } |
| new ExtensionDevToolsClientHost(contents_, |
|
pfeldman
2013/02/20 10:01:05
Can't you clone the target? Isn't it the Debuggee
Vladislav Kaznacheev
2013/02/20 12:02:26
I tried. The copy constructor of this class is pri
|
| GetExtension()->id(), |
| GetExtension()->name(), |
| - tab_id_); |
| + debuggee_tab_id_, |
| + debuggee_extension_id_); |
| SendResponse(true); |
| return true; |
| } |
| @@ -505,7 +589,10 @@ bool DebuggerDetachFunction::RunImpl() { |
| scoped_ptr<Detach::Params> params(Detach::Params::Create(*args_)); |
| EXTENSION_FUNCTION_VALIDATE(params.get()); |
| - tab_id_ = params->target.tab_id; |
| + if (params->target.tab_id) |
| + debuggee_tab_id_ = *params->target.tab_id; |
| + if (params->target.extension_id) |
| + debuggee_extension_id_ = *params->target.extension_id; |
| if (!InitClientHost()) |
| return false; |
| @@ -522,7 +609,10 @@ bool DebuggerSendCommandFunction::RunImpl() { |
| scoped_ptr<SendCommand::Params> params(SendCommand::Params::Create(*args_)); |
| EXTENSION_FUNCTION_VALIDATE(params.get()); |
| - tab_id_ = params->target.tab_id; |
| + if (params->target.tab_id) |
| + debuggee_tab_id_ = *params->target.tab_id; |
| + if (params->target.extension_id) |
| + debuggee_extension_id_ = *params->target.extension_id; |
| if (!InitClientHost()) |
| return false; |