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..d77cfbce892bc197d5df600ddcede1b4bef40c67 100644 |
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc |
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc |
@@ -9,6 +9,7 @@ |
#include <map> |
#include <set> |
+#include "base/command_line.h" |
#include "base/json/json_reader.h" |
#include "base/json/json_writer.h" |
#include "base/memory/scoped_ptr.h" |
@@ -20,12 +21,14 @@ |
#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" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" |
#include "chrome/common/chrome_notification_types.h" |
+#include "chrome/common/chrome_switches.h" |
#include "chrome/common/extensions/api/debugger.h" |
#include "chrome/common/extensions/extension.h" |
#include "content/public/browser/devtools_agent_host.h" |
@@ -33,7 +36,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 +50,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 +106,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 +136,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 +191,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. |
@@ -202,14 +216,16 @@ ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
web_contents_->GetRenderViewHost())); |
DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this); |
- 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 (!CommandLine::ForCurrentProcess()-> |
+ HasSwitch(switches::kExtensionDebuggingSilent)) { |
+ 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)); |
+ } |
} |
} |
@@ -277,9 +293,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 +343,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 +422,101 @@ bool ExtensionDevToolsInfoBarDelegate::Cancel() { |
DebuggerFunction::DebuggerFunction() |
: contents_(0), |
- tab_id_(0), |
+ debuggee_tab_id_(0), |
pfeldman
2013/02/20 14:58:39
debuggee_
Vladislav Kaznacheev
2013/02/20 15:24:50
Done.
|
client_host_(0) { |
} |
+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_); |
+} |
+ |
+static WebContents* FindWebContentsForExtension( |
+ const extensions::Extension* extension) { |
+ for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator()); |
+ !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; |
+ bool result = ExtensionTabUtil::GetTabById(debuggee_tab_id_, profile(), |
+ include_incognito(), NULL, NULL, &web_contents, NULL); |
+ if (!result || !web_contents) { |
+ FormatErrorMessage(keys::kNoTargetError); |
+ 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())) { |
- error_ = ErrorUtils::FormatErrorMessage( |
- keys::kAttachToWebUIError, |
- contents_->GetURL().scheme()); |
+ if (debuggee_extension_id_.size()) { |
+ if (!CommandLine::ForCurrentProcess()-> |
+ HasSwitch(switches::kExtensionDebuggingSilent)) { |
+ error_ = ErrorUtils::FormatErrorMessage( |
+ keys::kSilentDebuggingRequired, |
+ switches::kExtensionDebuggingSilent); |
+ return false; |
+ } |
+ |
+ const extensions::Extension* extension = profile()->GetExtensionService()-> |
+ extensions()->GetByID(debuggee_extension_id_); |
+ if (extension) { |
+ contents_ = FindWebContentsForExtension(extension); |
+ if (contents_) |
+ return true; |
+ } |
+ |
+ FormatErrorMessage(keys::kNoTargetError); |
return false; |
} |
- return true; |
+ error_ = keys::kInvalidTargetError; |
+ return false; |
} |
bool DebuggerFunction::InitClientHost() { |
@@ -449,9 +529,7 @@ bool DebuggerFunction::InitClientHost() { |
if (!client_host_ || |
!client_host_->MatchesContentsAndExtensionId(contents_, |
GetExtension()->id())) { |
- error_ = ErrorUtils::FormatErrorMessage( |
- keys::kNotAttachedError, |
- base::IntToString(tab_id_)); |
+ FormatErrorMessage(keys::kNotAttachedError); |
return false; |
} |
return true; |
@@ -465,7 +543,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; |
@@ -483,16 +564,15 @@ bool DebuggerAttachFunction::RunImpl() { |
GetDevToolsClientHostFor(agent); |
if (client_host != NULL) { |
- error_ = ErrorUtils::FormatErrorMessage( |
- keys::kAlreadyAttachedError, |
- base::IntToString(tab_id_)); |
+ FormatErrorMessage(keys::kAlreadyAttachedError); |
return false; |
} |
new ExtensionDevToolsClientHost(contents_, |
GetExtension()->id(), |
GetExtension()->name(), |
- tab_id_); |
+ debuggee_tab_id_, |
pfeldman
2013/02/20 14:58:39
Pass debuggee_ here and clone it in the constructo
Vladislav Kaznacheev
2013/02/20 15:24:50
Done.
|
+ debuggee_extension_id_); |
SendResponse(true); |
return true; |
} |
@@ -505,7 +585,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 +605,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; |