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 0d9b7e9cd34444aaa3c098531be5cd9daca1278d..2a8bb159ce7e0d32963a0dc1010da650db1a43fc 100644 |
--- a/content/browser/devtools/embedded_worker_devtools_manager.cc |
+++ b/content/browser/devtools/embedded_worker_devtools_manager.cc |
@@ -41,6 +41,14 @@ bool SendMessageToWorker( |
return true; |
} |
+enum WorkerState { |
+ WORKER_UNINSPECTED, |
+ WORKER_INSPECTED, |
+ WORKER_TERMINATED, |
+ WORKER_PAUSED_FOR_DEBUG_ON_START, |
+ WORKER_PAUSED_FOR_REATTACH, |
+}; |
+ |
} // namespace |
EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier( |
@@ -62,44 +70,29 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches( |
service_worker_version_id_ == other.service_worker_version_id_; |
} |
-EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo( |
- const SharedWorkerInstance& instance) |
- : shared_worker_instance_(new SharedWorkerInstance(instance)), |
- state_(WORKER_UNINSPECTED), |
- agent_host_(NULL) { |
-} |
- |
-EmbeddedWorkerDevToolsManager::WorkerInfo::WorkerInfo( |
- const ServiceWorkerIdentifier& service_worker_id) |
- : service_worker_id_(new ServiceWorkerIdentifier(service_worker_id)), |
- state_(WORKER_UNINSPECTED), |
- agent_host_(NULL) { |
-} |
- |
-bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches( |
- const SharedWorkerInstance& other) { |
- if (!shared_worker_instance_) |
- return false; |
- return shared_worker_instance_->Matches(other); |
-} |
- |
-bool EmbeddedWorkerDevToolsManager::WorkerInfo::Matches( |
- const ServiceWorkerIdentifier& other) { |
- if (!service_worker_id_) |
- return false; |
- return service_worker_id_->Matches(other); |
-} |
- |
-EmbeddedWorkerDevToolsManager::WorkerInfo::~WorkerInfo() { |
-} |
- |
class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost |
: public IPCDevToolsAgentHost, |
public IPC::Listener { |
public: |
- explicit EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id) |
- : worker_id_(worker_id), worker_attached_(false) { |
- AttachToWorker(); |
+ EmbeddedWorkerDevToolsAgentHost( |
+ WorkerId worker_id, |
+ const SharedWorkerInstance& shared_worker) |
+ : shared_worker_(new SharedWorkerInstance(shared_worker)), |
+ state_(WORKER_UNINSPECTED), |
+ worker_id_(worker_id) { |
+ WorkerCreated(); |
+ } |
+ |
+ EmbeddedWorkerDevToolsAgentHost( |
+ WorkerId worker_id, |
+ const ServiceWorkerIdentifier& service_worker, |
+ bool debug_service_worker_on_start) |
+ : service_worker_(new ServiceWorkerIdentifier(service_worker)), |
+ state_(WORKER_UNINSPECTED), |
+ worker_id_(worker_id) { |
+ if (debug_service_worker_on_start) |
+ state_ = WORKER_PAUSED_FOR_DEBUG_ON_START; |
+ WorkerCreated(); |
} |
// DevToolsAgentHost override. |
@@ -107,17 +100,28 @@ class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost |
// IPCDevToolsAgentHost implementation. |
virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE { |
- if (worker_attached_) |
+ if (state_ == WORKER_INSPECTED) |
SendMessageToWorker(worker_id_, message); |
else |
delete message; |
} |
+ |
virtual void Attach() OVERRIDE { |
- AttachToWorker(); |
+ if (state_ != WORKER_INSPECTED) { |
+ state_ = WORKER_INSPECTED; |
+ AttachToWorker(); |
+ } |
IPCDevToolsAgentHost::Attach(); |
} |
+ |
virtual void OnClientAttached() OVERRIDE {} |
- virtual void OnClientDetached() OVERRIDE { DetachFromWorker(); } |
+ |
+ virtual void OnClientDetached() OVERRIDE { |
+ if (state_ == WORKER_INSPECTED) { |
+ state_ = WORKER_UNINSPECTED; |
+ DetachFromWorker(); |
+ } |
+ } |
// IPC::Listener implementation. |
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE { |
@@ -133,31 +137,69 @@ class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost |
return handled; |
} |
- void ReattachToWorker(WorkerId worker_id) { |
- CHECK(!worker_attached_); |
+ void WorkerContextStarted() { |
+ if (state_ == WORKER_PAUSED_FOR_DEBUG_ON_START) { |
+ RenderProcessHost* rph = RenderProcessHost::FromID(worker_id_.first); |
+ DevToolsManagerImpl::GetInstance()->Inspect( |
+ rph->GetBrowserContext(), this); |
+ } else if (state_ == WORKER_PAUSED_FOR_REATTACH && IsAttached()) { |
+ state_ = WORKER_INSPECTED; |
+ AttachToWorker(); |
+ Reattach(saved_agent_state_); |
+ } |
+ } |
+ |
+ void WorkerRestarted(WorkerId worker_id) { |
+ DCHECK_EQ(state_, WORKER_TERMINATED); |
dgozman
2014/08/07 17:07:21
DCHECK_EQ (as well as other comparison macros like
|
+ state_ = WORKER_PAUSED_FOR_REATTACH; |
worker_id_ = worker_id; |
- if (!IsAttached()) |
- return; |
- AttachToWorker(); |
- Reattach(state_); |
+ WorkerCreated(); |
} |
- void DetachFromWorker() { |
- if (!worker_attached_) |
- return; |
- worker_attached_ = false; |
- if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) |
- host->RemoveRoute(worker_id_.second); |
- Release(); |
+ void WorkerDestroyed() { |
+ DCHECK_NE(state_, WORKER_TERMINATED); |
+ if (state_ == WORKER_INSPECTED) { |
+ DCHECK(IsAttached()); |
+ // Client host is debugging this worker agent host. |
+ std::string notification = |
+ DevToolsProtocol::CreateNotification( |
+ devtools::Worker::disconnectedFromWorker::kName, NULL) |
+ ->Serialize(); |
+ DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend( |
+ this, notification); |
+ DetachFromWorker(); |
+ } |
+ state_ = WORKER_TERMINATED; |
+ Release(); // Balanced in WorkerCreated() |
} |
- WorkerId worker_id() const { return worker_id_; } |
+ bool Matches(const SharedWorkerInstance& other) { |
+ return shared_worker_ && shared_worker_->Matches(other); |
+ } |
+ |
+ bool Matches(const ServiceWorkerIdentifier& other) { |
+ return service_worker_ && service_worker_->Matches(other); |
+ } |
private: |
virtual ~EmbeddedWorkerDevToolsAgentHost() { |
- CHECK(!worker_attached_); |
+ CHECK_EQ(state_, WORKER_TERMINATED); |
dgozman
2014/08/07 17:07:21
DCHECK_EQ
|
EmbeddedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData( |
- this); |
+ worker_id_); |
+ } |
+ |
+ void AttachToWorker() { |
+ if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) |
+ host->AddRoute(worker_id_.second, this); |
+ } |
+ |
+ void DetachFromWorker() { |
+ if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) |
+ host->RemoveRoute(worker_id_.second); |
+ } |
+ |
+ void WorkerCreated() { |
+ AddRef(); // Balanced in WorkerDestroyed() |
} |
void OnDispatchOnInspectorFrontend(const std::string& message) { |
@@ -165,20 +207,15 @@ class EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsAgentHost |
message); |
} |
- void OnSaveAgentRuntimeState(const std::string& state) { state_ = state; } |
- |
- void AttachToWorker() { |
- if (worker_attached_) |
- return; |
- worker_attached_ = true; |
- AddRef(); |
- if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) |
- host->AddRoute(worker_id_.second, this); |
+ void OnSaveAgentRuntimeState(const std::string& state) { |
+ saved_agent_state_ = state; |
} |
+ scoped_ptr<SharedWorkerInstance> shared_worker_; |
+ scoped_ptr<ServiceWorkerIdentifier> service_worker_; |
+ WorkerState state_; |
WorkerId worker_id_; |
- bool worker_attached_; |
- std::string state_; |
+ std::string saved_agent_state_; |
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost); |
}; |
@@ -191,29 +228,16 @@ EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() { |
DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker( |
int worker_process_id, |
int worker_route_id) { |
- WorkerId id(worker_process_id, worker_route_id); |
- |
- WorkerInfoMap::iterator it = workers_.find(id); |
- if (it == workers_.end()) |
- return NULL; |
- |
- WorkerInfo* info = it->second; |
- if (info->state() != WORKER_UNINSPECTED && |
- info->state() != WORKER_PAUSED_FOR_DEBUG_ON_START) { |
- return info->agent_host(); |
- } |
- |
- EmbeddedWorkerDevToolsAgentHost* agent_host = |
- new EmbeddedWorkerDevToolsAgentHost(id); |
- info->set_agent_host(agent_host); |
- info->set_state(WORKER_INSPECTED); |
- return agent_host; |
+ AgentHostMap::iterator it = workers_.find( |
+ WorkerId(worker_process_id, worker_route_id)); |
+ return it == workers_.end() ? NULL : it->second; |
} |
DevToolsAgentHost* |
EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker( |
const ServiceWorkerIdentifier& service_worker_id) { |
- WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id); |
+ AgentHostMap::iterator it = |
+ FindExistingServiceWorkerAgentHost(service_worker_id); |
if (it == workers_.end()) |
return NULL; |
return GetDevToolsAgentHostForWorker(it->first.first, it->first.second); |
@@ -232,13 +256,12 @@ bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated( |
const SharedWorkerInstance& instance) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
const WorkerId id(worker_process_id, worker_route_id); |
- WorkerInfoMap::iterator it = FindExistingSharedWorkerInfo(instance); |
+ AgentHostMap::iterator it = FindExistingSharedWorkerAgentHost(instance); |
if (it == workers_.end()) { |
- scoped_ptr<WorkerInfo> info(new WorkerInfo(instance)); |
- workers_.set(id, info.Pass()); |
+ workers_[id] = new EmbeddedWorkerDevToolsAgentHost(id, instance); |
return false; |
} |
- MoveToPausedState(id, it); |
+ WorkerRestarted(id, it); |
return true; |
} |
@@ -248,15 +271,14 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated( |
const ServiceWorkerIdentifier& service_worker_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
const WorkerId id(worker_process_id, worker_route_id); |
- WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id); |
+ AgentHostMap::iterator it = |
+ FindExistingServiceWorkerAgentHost(service_worker_id); |
if (it == workers_.end()) { |
- scoped_ptr<WorkerInfo> info(new WorkerInfo(service_worker_id)); |
- if (debug_service_worker_on_start_) |
- info->set_state(WORKER_PAUSED_FOR_DEBUG_ON_START); |
- workers_.set(id, info.Pass()); |
+ workers_[id] = new EmbeddedWorkerDevToolsAgentHost( |
+ id, service_worker_id, debug_service_worker_on_start_); |
return debug_service_worker_on_start_; |
} |
- MoveToPausedState(id, it); |
+ WorkerRestarted(id, it); |
return true; |
} |
@@ -264,96 +286,29 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id, |
int worker_route_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
const WorkerId id(worker_process_id, worker_route_id); |
- WorkerInfoMap::iterator it = workers_.find(id); |
+ AgentHostMap::iterator it = workers_.find(id); |
DCHECK(it != workers_.end()); |
- WorkerInfo* info = it->second; |
- switch (info->state()) { |
- case WORKER_UNINSPECTED: |
- case WORKER_PAUSED_FOR_DEBUG_ON_START: |
- workers_.erase(it); |
- break; |
- case WORKER_INSPECTED: { |
- EmbeddedWorkerDevToolsAgentHost* agent_host = info->agent_host(); |
- info->set_state(WORKER_TERMINATED); |
- if (!agent_host->IsAttached()) { |
- agent_host->DetachFromWorker(); |
- return; |
- } |
- // Client host is debugging this worker agent host. |
- std::string notification = |
- DevToolsProtocol::CreateNotification( |
- devtools::Worker::disconnectedFromWorker::kName, NULL) |
- ->Serialize(); |
- DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend( |
- agent_host, notification); |
- agent_host->DetachFromWorker(); |
- break; |
- } |
- case WORKER_TERMINATED: |
- NOTREACHED(); |
- break; |
- 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(); |
- workers_.set(old_id, worker_info.Pass()); |
- break; |
- } |
- } |
+ it->second->WorkerDestroyed(); |
} |
void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id, |
int worker_route_id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
const WorkerId id(worker_process_id, worker_route_id); |
- WorkerInfoMap::iterator it = workers_.find(id); |
+ AgentHostMap::iterator it = workers_.find(id); |
DCHECK(it != workers_.end()); |
- WorkerInfo* info = it->second; |
- if (info->state() == WORKER_PAUSED_FOR_DEBUG_ON_START) { |
- 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()); |
- } else if (info->state() == WORKER_PAUSED_FOR_REATTACH) { |
- info->agent_host()->ReattachToWorker(id); |
- info->set_state(WORKER_INSPECTED); |
- } |
+ it->second->WorkerContextStarted(); |
} |
-void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData( |
- EmbeddedWorkerDevToolsAgentHost* agent_host) { |
+void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(WorkerId id) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- const WorkerId id(agent_host->worker_id()); |
- scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(id); |
- if (worker_info) { |
- DCHECK_EQ(worker_info->agent_host(), agent_host); |
- if (worker_info->state() == WORKER_TERMINATED) |
- return; |
- DCHECK_EQ(worker_info->state(), WORKER_INSPECTED); |
- worker_info->set_agent_host(NULL); |
- worker_info->set_state(WORKER_UNINSPECTED); |
- workers_.set(id, worker_info.Pass()); |
- return; |
- } |
- for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end(); |
- ++it) { |
- if (it->second->agent_host() == agent_host) { |
- DCHECK_EQ(WORKER_PAUSED_FOR_REATTACH, it->second->state()); |
- SendMessageToWorker( |
- it->first, |
- new DevToolsAgentMsg_ResumeWorkerContext(it->first.second)); |
- it->second->set_agent_host(NULL); |
- it->second->set_state(WORKER_UNINSPECTED); |
- return; |
- } |
- } |
+ workers_.erase(id); |
} |
-EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator |
-EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerInfo( |
+EmbeddedWorkerDevToolsManager::AgentHostMap::iterator |
+EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerAgentHost( |
const SharedWorkerInstance& instance) { |
- WorkerInfoMap::iterator it = workers_.begin(); |
+ AgentHostMap::iterator it = workers_.begin(); |
for (; it != workers_.end(); ++it) { |
if (it->second->Matches(instance)) |
break; |
@@ -361,10 +316,10 @@ EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerInfo( |
return it; |
} |
-EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator |
-EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerInfo( |
+EmbeddedWorkerDevToolsManager::AgentHostMap::iterator |
+EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerAgentHost( |
const ServiceWorkerIdentifier& service_worker_id) { |
- WorkerInfoMap::iterator it = workers_.begin(); |
+ AgentHostMap::iterator it = workers_.begin(); |
for (; it != workers_.end(); ++it) { |
if (it->second->Matches(service_worker_id)) |
break; |
@@ -372,13 +327,13 @@ EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerInfo( |
return it; |
} |
-void EmbeddedWorkerDevToolsManager::MoveToPausedState( |
+void EmbeddedWorkerDevToolsManager::WorkerRestarted( |
const WorkerId& id, |
- 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_FOR_REATTACH); |
- workers_.set(id, info.Pass()); |
+ const AgentHostMap::iterator& it) { |
+ EmbeddedWorkerDevToolsAgentHost* agent_host = it->second; |
+ agent_host->WorkerRestarted(id); |
+ workers_.erase(it); |
+ workers_[id] = agent_host; |
} |
void EmbeddedWorkerDevToolsManager::ResetForTesting() { |