| 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());
|
| }
|
|
|
|
|