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