Index: content/browser/devtools/embedded_worker_devtools_manager.cc |
diff --git a/content/browser/devtools/embedded_worker_devtools_manager.cc b/content/browser/devtools/embedded_worker_devtools_manager.cc |
index 7d804f704e12e3896c2cd9979ddcc07d2b204461..bb4613baa3ac3a924999db7d3ca6cd3ae18afb08 100644 |
--- a/content/browser/devtools/embedded_worker_devtools_manager.cc |
+++ b/content/browser/devtools/embedded_worker_devtools_manager.cc |
@@ -56,13 +56,16 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches( |
EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo( |
const SharedWorkerInstance& instance) |
: shared_worker_instance_(new SharedWorkerInstance(instance)), |
+ debug_on_start_(false), |
state_(WORKER_UNINSPECTED), |
agent_host_(NULL) { |
} |
EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo( |
- const ServiceWorkerIdentifier& service_worker_id) |
+ const ServiceWorkerIdentifier& service_worker_id, |
+ bool debug_on_start) |
: service_worker_id_(new ServiceWorkerIdentifier(service_worker_id)), |
+ debug_on_start_(debug_on_start), |
state_(WORKER_UNINSPECTED), |
agent_host_(NULL) { |
} |
@@ -88,8 +91,11 @@ class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost |
: public IPCDevToolsAgentHost, |
public IPC::Listener { |
public: |
- explicit EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id) |
- : worker_id_(worker_id), worker_attached_(true) { |
+ explicit EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id, |
+ bool debug_on_start) |
+ : worker_id_(worker_id), |
+ worker_attached_(true), |
+ paused_for_debug_on_start_(debug_on_start) { |
AddRef(); |
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) |
host->AddRoute(worker_id_.second, this); |
@@ -97,9 +103,30 @@ class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost |
// DevToolsAgentHost override. |
virtual bool IsWorker() const OVERRIDE { return true; } |
+ virtual bool IsWorkerPaused() const OVERRIDE { |
+ // If IsWorkerPaused returns true, DevTools window will be opend with |
+ // "workerPaused" option. And the script execution of ServiceWorker will be |
+ // resumed and then paused on the first script statement. This is done by |
+ // calling Debugger.pause and Runtime.run from the DevTools front end. |
+ return paused_for_debug_on_start_; |
+ } |
// IPCDevToolsAgentHost implementation. |
virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE { |
+ if (paused_for_debug_on_start_ && |
+ message->type() == DevToolsAgentMsg_DispatchOnInspectorBackend::ID) { |
+ // This is a bit tricky but we have to clear |paused_for_debug_on_start_| |
+ // when "Runtime.run" is called from the DevTools front end. Otherwise |
+ // when the user reopens the DevTools later the SharedWorker will be |
+ // paused because the DevTools front end will call Debugger.pause and |
+ // Runtime.run again. |
+ DevToolsAgentMsg_DispatchOnInspectorBackend::Param params; |
+ if (DevToolsAgentMsg_DispatchOnInspectorBackend::Read(message, ¶ms) && |
+ params.a.find("Runtime.run") != std::string::npos) { |
+ paused_for_debug_on_start_ = false; |
+ } |
+ } |
+ |
if (worker_attached_) |
SendMessageToWorker(worker_id_, message); |
else |
@@ -158,6 +185,7 @@ class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost |
WorkerId worker_id_; |
bool worker_attached_; |
+ bool paused_for_debug_on_start_; |
std::string state_; |
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost); |
}; |
@@ -182,7 +210,7 @@ DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker( |
return info->agent_host(); |
EmbeddedWorkerDevToolsAgentHost* agent_host = |
- new EmbeddedWorkerDevToolsAgentHost(id); |
+ new EmbeddedWorkerDevToolsAgentHost(id, info->debug_on_start()); |
info->set_agent_host(agent_host); |
info->set_state(WORKER_INSPECTED); |
return agent_host; |
@@ -197,7 +225,8 @@ EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker( |
return GetDevToolsAgentHostForWorker(it->first.first, it->first.second); |
} |
-EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() { |
+EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() |
+ : debug_service_worker_on_start_(false) { |
} |
EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() { |
@@ -227,9 +256,10 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated( |
const WorkerId id(worker_process_id, worker_route_id); |
WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id); |
if (it == workers_.end()) { |
- scoped_ptr<WorkerInfo> info(new WorkerInfo(service_worker_id)); |
+ scoped_ptr<WorkerInfo> info( |
+ new WorkerInfo(service_worker_id, debug_service_worker_on_start_)); |
workers_.set(id, info.Pass()); |
- return false; |
+ return debug_service_worker_on_start_; |
} |
MoveToPausedState(id, it); |
return true; |
@@ -267,7 +297,7 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id, |
case WORKER_TERMINATED: |
NOTREACHED(); |
break; |
- case WORKER_PAUSED: { |
+ case WORKER_PAUSED_FOR_REATTACH: { |
scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it); |
worker_info->set_state(WORKER_TERMINATED); |
const WorkerId old_id = worker_info->agent_host()->worker_id(); |
@@ -284,8 +314,16 @@ void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id, |
WorkerInfoMap::iterator it = workers_.find(id); |
DCHECK(it != workers_.end()); |
WorkerInfo* info = it->second; |
- if (info->state() != WORKER_PAUSED) |
+ if (info->state() != WORKER_PAUSED_FOR_REATTACH) { |
+ if (!info->debug_on_start()) |
+ return; |
+ RenderProcessHost* rph = RenderProcessHost::FromID(worker_process_id); |
+ scoped_refptr<DevToolsAgentHost> agent_host( |
+ GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id)); |
+ DevToolsManagerImpl::GetInstance()->Inspect(rph->GetBrowserContext(), |
+ agent_host.get()); |
return; |
+ } |
info->agent_host()->ReattachToWorker(id); |
info->set_state(WORKER_INSPECTED); |
} |
@@ -302,7 +340,7 @@ void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData( |
for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end(); |
++it) { |
if (it->second->agent_host() == agent_host) { |
- DCHECK_EQ(WORKER_PAUSED, it->second->state()); |
+ DCHECK_EQ(WORKER_PAUSED_FOR_REATTACH, it->second->state()); |
SendMessageToWorker( |
it->first, |
new DevToolsAgentMsg_ResumeWorkerContext(it->first.second)); |
@@ -340,7 +378,7 @@ void EmbeddedWorkerDevToolsManager::MoveToPausedState( |
const WorkerInfoMap::iterator& it) { |
DCHECK_EQ(WORKER_TERMINATED, it->second->state()); |
scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it); |
- info->set_state(WORKER_PAUSED); |
+ info->set_state(WORKER_PAUSED_FOR_REATTACH); |
workers_.set(id, info.Pass()); |
} |