DevTools: Merge WorkerInfo into EmbeddedWorkerDevToolsAgentHost

Fixes issues with EWDTAH lifetime. Now EWDTAH lives as long as there is a scoped_refptr referencing it or the worker is alive.

Split off https://codereview.chromium.org/349033009/

BUG=389454

Review URL: https://codereview.chromium.org/405603002

Cr-Commit-Position: refs/heads/master@{#288362}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288362 0039d316-1c4b-4281-b951-d872f2087c98
parent 3fb3f9ed
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/devtools/embedded_worker_devtools_agent_host.h"
#include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/devtools_protocol.h"
#include "content/browser/devtools/devtools_protocol_constants.h"
#include "content/common/devtools_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
namespace content {
EmbeddedWorkerDevToolsAgentHost::EmbeddedWorkerDevToolsAgentHost(
WorkerId worker_id,
const SharedWorkerInstance& shared_worker)
: shared_worker_(new SharedWorkerInstance(shared_worker)),
state_(WORKER_UNINSPECTED),
worker_id_(worker_id) {
WorkerCreated();
}
EmbeddedWorkerDevToolsAgentHost::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();
}
bool EmbeddedWorkerDevToolsAgentHost::IsWorker() const {
return true;
}
void EmbeddedWorkerDevToolsAgentHost::SendMessageToAgent(
IPC::Message* message_raw) {
scoped_ptr<IPC::Message> message(message_raw);
if (state_ != WORKER_INSPECTED)
return;
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first)) {
message->set_routing_id(worker_id_.second);
host->Send(message.release());
}
}
void EmbeddedWorkerDevToolsAgentHost::Attach() {
if (state_ != WORKER_INSPECTED) {
state_ = WORKER_INSPECTED;
AttachToWorker();
}
IPCDevToolsAgentHost::Attach();
}
void EmbeddedWorkerDevToolsAgentHost::OnClientDetached() {
if (state_ == WORKER_INSPECTED) {
state_ = WORKER_UNINSPECTED;
DetachFromWorker();
} else if (state_ == WORKER_PAUSED_FOR_REATTACH) {
state_ = WORKER_UNINSPECTED;
}
}
bool EmbeddedWorkerDevToolsAgentHost::OnMessageReceived(
const IPC::Message& msg) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerDevToolsAgentHost, msg)
IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
OnDispatchOnInspectorFrontend)
IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
OnSaveAgentRuntimeState)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void EmbeddedWorkerDevToolsAgentHost::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) {
DCHECK(IsAttached());
state_ = WORKER_INSPECTED;
AttachToWorker();
Reattach(saved_agent_state_);
}
}
void EmbeddedWorkerDevToolsAgentHost::WorkerRestarted(WorkerId worker_id) {
DCHECK_EQ(WORKER_TERMINATED, state_);
state_ = IsAttached() ? WORKER_PAUSED_FOR_REATTACH : WORKER_UNINSPECTED;
worker_id_ = worker_id;
WorkerCreated();
}
void EmbeddedWorkerDevToolsAgentHost::WorkerDestroyed() {
DCHECK_NE(WORKER_TERMINATED, state_);
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()
}
bool EmbeddedWorkerDevToolsAgentHost::Matches(
const SharedWorkerInstance& other) {
return shared_worker_ && shared_worker_->Matches(other);
}
bool EmbeddedWorkerDevToolsAgentHost::Matches(
const ServiceWorkerIdentifier& other) {
return service_worker_ && service_worker_->Matches(other);
}
EmbeddedWorkerDevToolsAgentHost::~EmbeddedWorkerDevToolsAgentHost() {
DCHECK_EQ(WORKER_TERMINATED, state_);
EmbeddedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(
worker_id_);
}
void EmbeddedWorkerDevToolsAgentHost::AttachToWorker() {
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
host->AddRoute(worker_id_.second, this);
}
void EmbeddedWorkerDevToolsAgentHost::DetachFromWorker() {
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
host->RemoveRoute(worker_id_.second);
}
void EmbeddedWorkerDevToolsAgentHost::WorkerCreated() {
AddRef(); // Balanced in WorkerDestroyed()
}
void EmbeddedWorkerDevToolsAgentHost::OnDispatchOnInspectorFrontend(
const std::string& message) {
DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(
this, message);
}
void EmbeddedWorkerDevToolsAgentHost::OnSaveAgentRuntimeState(
const std::string& state) {
saved_agent_state_ = state;
}
} // namespace content
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_AGENT_HOST_H_
#define CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_AGENT_HOST_H_
#include "content/browser/devtools/embedded_worker_devtools_manager.h"
#include "content/browser/devtools/ipc_devtools_agent_host.h"
#include "ipc/ipc_listener.h"
namespace content {
class SharedWorkerInstance;
class EmbeddedWorkerDevToolsAgentHost : public IPCDevToolsAgentHost,
public IPC::Listener {
public:
typedef EmbeddedWorkerDevToolsManager::WorkerId WorkerId;
typedef EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier
ServiceWorkerIdentifier;
EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id,
const SharedWorkerInstance& shared_worker);
EmbeddedWorkerDevToolsAgentHost(WorkerId worker_id,
const ServiceWorkerIdentifier& service_worker,
bool debug_service_worker_on_start);
// DevToolsAgentHost override.
virtual bool IsWorker() const OVERRIDE;
// IPCDevToolsAgentHost implementation.
virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE;
virtual void Attach() OVERRIDE;
virtual void OnClientAttached() OVERRIDE {}
virtual void OnClientDetached() OVERRIDE;
// IPC::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
void WorkerContextStarted();
void WorkerRestarted(WorkerId worker_id);
void WorkerDestroyed();
bool Matches(const SharedWorkerInstance& other);
bool Matches(const ServiceWorkerIdentifier& other);
private:
friend class EmbeddedWorkerDevToolsManagerTest;
virtual ~EmbeddedWorkerDevToolsAgentHost();
enum WorkerState {
WORKER_UNINSPECTED,
WORKER_INSPECTED,
WORKER_TERMINATED,
WORKER_PAUSED_FOR_DEBUG_ON_START,
WORKER_PAUSED_FOR_REATTACH,
};
void AttachToWorker();
void DetachFromWorker();
void WorkerCreated();
void OnDispatchOnInspectorFrontend(const std::string& message);
void OnSaveAgentRuntimeState(const std::string& state);
scoped_ptr<SharedWorkerInstance> shared_worker_;
scoped_ptr<ServiceWorkerIdentifier> service_worker_;
WorkerState state_;
WorkerId worker_id_;
std::string saved_agent_state_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost);
};
} // namespace content
#endif // CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_AGENT_HOST_H_
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "content/browser/devtools/devtools_manager_impl.h" #include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/devtools_protocol.h" #include "content/browser/devtools/devtools_protocol.h"
#include "content/browser/devtools/devtools_protocol_constants.h" #include "content/browser/devtools/devtools_protocol_constants.h"
#include "content/browser/devtools/embedded_worker_devtools_agent_host.h"
#include "content/browser/devtools/ipc_devtools_agent_host.h" #include "content/browser/devtools/ipc_devtools_agent_host.h"
#include "content/browser/shared_worker/shared_worker_instance.h" #include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/common/devtools_messages.h" #include "content/common/devtools_messages.h"
...@@ -26,23 +27,6 @@ scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForWorker( ...@@ -26,23 +27,6 @@ scoped_refptr<DevToolsAgentHost> DevToolsAgentHost::GetForWorker(
->GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id); ->GetDevToolsAgentHostForWorker(worker_process_id, worker_route_id);
} }
namespace {
bool SendMessageToWorker(
const EmbeddedWorkerDevToolsManager::WorkerId& worker_id,
IPC::Message* message) {
RenderProcessHost* host = RenderProcessHost::FromID(worker_id.first);
if (!host) {
delete message;
return false;
}
message->set_routing_id(worker_id.second);
host->Send(message);
return true;
}
} // namespace
EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier( EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::ServiceWorkerIdentifier(
const ServiceWorkerContextCore* const service_worker_context, const ServiceWorkerContextCore* const service_worker_context,
int64 service_worker_version_id) int64 service_worker_version_id)
...@@ -62,126 +46,6 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches( ...@@ -62,126 +46,6 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerIdentifier::Matches(
service_worker_version_id_ == other.service_worker_version_id_; 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();
}
// DevToolsAgentHost override.
virtual bool IsWorker() const OVERRIDE { return true; }
// IPCDevToolsAgentHost implementation.
virtual void SendMessageToAgent(IPC::Message* message) OVERRIDE {
if (worker_attached_)
SendMessageToWorker(worker_id_, message);
else
delete message;
}
virtual void Attach() OVERRIDE {
AttachToWorker();
IPCDevToolsAgentHost::Attach();
}
virtual void OnClientAttached() OVERRIDE {}
virtual void OnClientDetached() OVERRIDE { DetachFromWorker(); }
// IPC::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerDevToolsAgentHost, msg)
IPC_MESSAGE_HANDLER(DevToolsClientMsg_DispatchOnInspectorFrontend,
OnDispatchOnInspectorFrontend)
IPC_MESSAGE_HANDLER(DevToolsHostMsg_SaveAgentRuntimeState,
OnSaveAgentRuntimeState)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void ReattachToWorker(WorkerId worker_id) {
CHECK(!worker_attached_);
worker_id_ = worker_id;
if (!IsAttached())
return;
AttachToWorker();
Reattach(state_);
}
void DetachFromWorker() {
if (!worker_attached_)
return;
worker_attached_ = false;
if (RenderProcessHost* host = RenderProcessHost::FromID(worker_id_.first))
host->RemoveRoute(worker_id_.second);
Release();
}
WorkerId worker_id() const { return worker_id_; }
private:
virtual ~EmbeddedWorkerDevToolsAgentHost() {
CHECK(!worker_attached_);
EmbeddedWorkerDevToolsManager::GetInstance()->RemoveInspectedWorkerData(
this);
}
void OnDispatchOnInspectorFrontend(const std::string& message) {
DevToolsManagerImpl::GetInstance()->DispatchOnInspectorFrontend(this,
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);
}
WorkerId worker_id_;
bool worker_attached_;
std::string state_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsAgentHost);
};
// static // static
EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() { EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
...@@ -191,29 +55,16 @@ EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() { ...@@ -191,29 +55,16 @@ EmbeddedWorkerDevToolsManager* EmbeddedWorkerDevToolsManager::GetInstance() {
DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker( DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
int worker_process_id, int worker_process_id,
int worker_route_id) { int worker_route_id) {
WorkerId id(worker_process_id, worker_route_id); AgentHostMap::iterator it = workers_.find(
WorkerId(worker_process_id, worker_route_id));
WorkerInfoMap::iterator it = workers_.find(id); return it == workers_.end() ? NULL : it->second;
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;
} }
DevToolsAgentHost* DevToolsAgentHost*
EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker( EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker(
const ServiceWorkerIdentifier& service_worker_id) { const ServiceWorkerIdentifier& service_worker_id) {
WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id); AgentHostMap::iterator it =
FindExistingServiceWorkerAgentHost(service_worker_id);
if (it == workers_.end()) if (it == workers_.end())
return NULL; return NULL;
return GetDevToolsAgentHostForWorker(it->first.first, it->first.second); return GetDevToolsAgentHostForWorker(it->first.first, it->first.second);
...@@ -232,13 +83,12 @@ bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated( ...@@ -232,13 +83,12 @@ bool EmbeddedWorkerDevToolsManager::SharedWorkerCreated(
const SharedWorkerInstance& instance) { const SharedWorkerInstance& instance) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const WorkerId id(worker_process_id, worker_route_id); const WorkerId id(worker_process_id, worker_route_id);
WorkerInfoMap::iterator it = FindExistingSharedWorkerInfo(instance); AgentHostMap::iterator it = FindExistingSharedWorkerAgentHost(instance);
if (it == workers_.end()) { if (it == workers_.end()) {
scoped_ptr<WorkerInfo> info(new WorkerInfo(instance)); workers_[id] = new EmbeddedWorkerDevToolsAgentHost(id, instance);
workers_.set(id, info.Pass());
return false; return false;
} }
MoveToPausedState(id, it); WorkerRestarted(id, it);
return true; return true;
} }
...@@ -248,15 +98,14 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated( ...@@ -248,15 +98,14 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated(
const ServiceWorkerIdentifier& service_worker_id) { const ServiceWorkerIdentifier& service_worker_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const WorkerId id(worker_process_id, worker_route_id); 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()) { if (it == workers_.end()) {
scoped_ptr<WorkerInfo> info(new WorkerInfo(service_worker_id)); workers_[id] = new EmbeddedWorkerDevToolsAgentHost(
if (debug_service_worker_on_start_) id, service_worker_id, debug_service_worker_on_start_);
info->set_state(WORKER_PAUSED_FOR_DEBUG_ON_START);
workers_.set(id, info.Pass());
return debug_service_worker_on_start_; return debug_service_worker_on_start_;
} }
MoveToPausedState(id, it); WorkerRestarted(id, it);
return true; return true;
} }
...@@ -264,96 +113,29 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id, ...@@ -264,96 +113,29 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
int worker_route_id) { int worker_route_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const WorkerId id(worker_process_id, worker_route_id); 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()); DCHECK(it != workers_.end());
WorkerInfo* info = it->second; it->second->WorkerDestroyed();
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;
}
}
} }
void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id, void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
int worker_route_id) { int worker_route_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const WorkerId id(worker_process_id, worker_route_id); 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()); DCHECK(it != workers_.end());
WorkerInfo* info = it->second; it->second->WorkerContextStarted();
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);
}
} }
void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData( void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(WorkerId id) {
EmbeddedWorkerDevToolsAgentHost* agent_host) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const WorkerId id(agent_host->worker_id()); workers_.erase(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;
}
}
} }
EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator EmbeddedWorkerDevToolsManager::AgentHostMap::iterator
EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerInfo( EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerAgentHost(
const SharedWorkerInstance& instance) { const SharedWorkerInstance& instance) {
WorkerInfoMap::iterator it = workers_.begin(); AgentHostMap::iterator it = workers_.begin();
for (; it != workers_.end(); ++it) { for (; it != workers_.end(); ++it) {
if (it->second->Matches(instance)) if (it->second->Matches(instance))
break; break;
...@@ -361,10 +143,10 @@ EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerInfo( ...@@ -361,10 +143,10 @@ EmbeddedWorkerDevToolsManager::FindExistingSharedWorkerInfo(
return it; return it;
} }
EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator EmbeddedWorkerDevToolsManager::AgentHostMap::iterator
EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerInfo( EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerAgentHost(
const ServiceWorkerIdentifier& service_worker_id) { const ServiceWorkerIdentifier& service_worker_id) {
WorkerInfoMap::iterator it = workers_.begin(); AgentHostMap::iterator it = workers_.begin();
for (; it != workers_.end(); ++it) { for (; it != workers_.end(); ++it) {
if (it->second->Matches(service_worker_id)) if (it->second->Matches(service_worker_id))
break; break;
...@@ -372,13 +154,13 @@ EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerInfo( ...@@ -372,13 +154,13 @@ EmbeddedWorkerDevToolsManager::FindExistingServiceWorkerInfo(
return it; return it;
} }
void EmbeddedWorkerDevToolsManager::MoveToPausedState( void EmbeddedWorkerDevToolsManager::WorkerRestarted(
const WorkerId& id, const WorkerId& id,
const WorkerInfoMap::iterator& it) { const AgentHostMap::iterator& it) {
DCHECK_EQ(WORKER_TERMINATED, it->second->state()); EmbeddedWorkerDevToolsAgentHost* agent_host = it->second;
scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it); agent_host->WorkerRestarted(id);
info->set_state(WORKER_PAUSED_FOR_REATTACH); workers_.erase(it);
workers_.set(id, info.Pass()); workers_[id] = agent_host;
} }
void EmbeddedWorkerDevToolsManager::ResetForTesting() { void EmbeddedWorkerDevToolsManager::ResetForTesting() {
......
...@@ -5,8 +5,9 @@ ...@@ -5,8 +5,9 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_ #ifndef CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
#define CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_ #define CONTENT_BROWSER_DEVTOOLS_EMBEDDED_WORKER_DEVTOOLS_MANAGER_H_
#include <map>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/containers/scoped_ptr_hash_map.h"
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
namespace content { namespace content {
class DevToolsAgentHost; class DevToolsAgentHost;
class EmbeddedWorkerDevToolsAgentHost;
class ServiceWorkerContextCore; class ServiceWorkerContextCore;
// EmbeddedWorkerDevToolsManager is used instead of WorkerDevToolsManager when // EmbeddedWorkerDevToolsManager is used instead of WorkerDevToolsManager when
...@@ -25,7 +27,6 @@ class ServiceWorkerContextCore; ...@@ -25,7 +27,6 @@ class ServiceWorkerContextCore;
class CONTENT_EXPORT EmbeddedWorkerDevToolsManager { class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
public: public:
typedef std::pair<int, int> WorkerId; typedef std::pair<int, int> WorkerId;
class EmbeddedWorkerDevToolsAgentHost;
class ServiceWorkerIdentifier { class ServiceWorkerIdentifier {
public: public:
...@@ -73,60 +74,29 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager { ...@@ -73,60 +74,29 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
private: private:
friend struct DefaultSingletonTraits<EmbeddedWorkerDevToolsManager>; friend struct DefaultSingletonTraits<EmbeddedWorkerDevToolsManager>;
friend class EmbeddedWorkerDevToolsAgentHost;
friend class EmbeddedWorkerDevToolsManagerTest; friend class EmbeddedWorkerDevToolsManagerTest;
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, BasicTest); FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, BasicTest);
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, AttachTest); FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerDevToolsManagerTest, AttachTest);
enum WorkerState { typedef std::map<WorkerId, EmbeddedWorkerDevToolsAgentHost*> AgentHostMap;
WORKER_UNINSPECTED,
WORKER_INSPECTED,
WORKER_TERMINATED,
WORKER_PAUSED_FOR_DEBUG_ON_START,
WORKER_PAUSED_FOR_REATTACH,
};
class WorkerInfo {
public:
// Creates WorkerInfo for SharedWorker.
explicit WorkerInfo(const SharedWorkerInstance& instance);
// Creates WorkerInfo for ServiceWorker.
explicit WorkerInfo(const ServiceWorkerIdentifier& service_worker_id);
~WorkerInfo();
WorkerState state() { return state_; }
void set_state(WorkerState new_state) { state_ = new_state; }
EmbeddedWorkerDevToolsAgentHost* agent_host() { return agent_host_; }
void set_agent_host(EmbeddedWorkerDevToolsAgentHost* agent_host) {
agent_host_ = agent_host;
}
bool Matches(const SharedWorkerInstance& other);
bool Matches(const ServiceWorkerIdentifier& other);
private:
scoped_ptr<SharedWorkerInstance> shared_worker_instance_;
scoped_ptr<ServiceWorkerIdentifier> service_worker_id_;
WorkerState state_;
EmbeddedWorkerDevToolsAgentHost* agent_host_;
};
typedef base::ScopedPtrHashMap<WorkerId, WorkerInfo> WorkerInfoMap;
EmbeddedWorkerDevToolsManager(); EmbeddedWorkerDevToolsManager();
virtual ~EmbeddedWorkerDevToolsManager(); virtual ~EmbeddedWorkerDevToolsManager();
void RemoveInspectedWorkerData(EmbeddedWorkerDevToolsAgentHost* agent_host); void RemoveInspectedWorkerData(WorkerId id);
WorkerInfoMap::iterator FindExistingSharedWorkerInfo( AgentHostMap::iterator FindExistingSharedWorkerAgentHost(
const SharedWorkerInstance& instance); const SharedWorkerInstance& instance);
WorkerInfoMap::iterator FindExistingServiceWorkerInfo( AgentHostMap::iterator FindExistingServiceWorkerAgentHost(
const ServiceWorkerIdentifier& service_worker_id); const ServiceWorkerIdentifier& service_worker_id);
void MoveToPausedState(const WorkerId& id, const WorkerInfoMap::iterator& it); void WorkerRestarted(const WorkerId& id, const AgentHostMap::iterator& it);
// Resets to its initial state as if newly created. // Resets to its initial state as if newly created.
void ResetForTesting(); void ResetForTesting();
WorkerInfoMap workers_; AgentHostMap workers_;
bool debug_service_worker_on_start_; bool debug_service_worker_on_start_;
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "content/browser/browser_thread_impl.h" #include "content/browser/browser_thread_impl.h"
#include "content/browser/devtools/devtools_manager_impl.h" #include "content/browser/devtools/devtools_manager_impl.h"
#include "content/browser/devtools/embedded_worker_devtools_agent_host.h"
#include "content/browser/shared_worker/shared_worker_instance.h" #include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/worker_storage_partition.h" #include "content/browser/shared_worker/worker_storage_partition.h"
#include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host.h"
...@@ -35,6 +36,8 @@ class TestDevToolsClientHost : public DevToolsClientHost { ...@@ -35,6 +36,8 @@ class TestDevToolsClientHost : public DevToolsClientHost {
class EmbeddedWorkerDevToolsManagerTest : public testing::Test { class EmbeddedWorkerDevToolsManagerTest : public testing::Test {
public: public:
typedef EmbeddedWorkerDevToolsAgentHost::WorkerState WorkerState;
EmbeddedWorkerDevToolsManagerTest() EmbeddedWorkerDevToolsManagerTest()
: ui_thread_(BrowserThread::UI, &message_loop_), : ui_thread_(BrowserThread::UI, &message_loop_),
browser_context_(new TestBrowserContext()), browser_context_(new TestBrowserContext()),
...@@ -59,13 +62,13 @@ class EmbeddedWorkerDevToolsManagerTest : public testing::Test { ...@@ -59,13 +62,13 @@ class EmbeddedWorkerDevToolsManagerTest : public testing::Test {
void CheckWorkerState(int worker_process_id, void CheckWorkerState(int worker_process_id,
int worker_route_id, int worker_route_id,
EmbeddedWorkerDevToolsManager::WorkerState state) { WorkerState state) {
const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id, const EmbeddedWorkerDevToolsManager::WorkerId id(worker_process_id,
worker_route_id); worker_route_id);
EmbeddedWorkerDevToolsManager::WorkerInfoMap::iterator it = EmbeddedWorkerDevToolsManager::AgentHostMap::iterator it =
manager_->workers_.find(id); manager_->workers_.find(id);
EXPECT_TRUE(manager_->workers_.end() != it); EXPECT_TRUE(manager_->workers_.end() != it);
EXPECT_EQ(state, it->second->state()); EXPECT_EQ(state, it->second->state_);
} }
void CheckWorkerNotExist(int worker_process_id, int worker_route_id) { void CheckWorkerNotExist(int worker_process_id, int worker_route_id) {
...@@ -112,67 +115,67 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, BasicTest) { ...@@ -112,67 +115,67 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, BasicTest) {
// Created -> Started -> Destroyed // Created -> Started -> Destroyed
CheckWorkerNotExist(1, 1); CheckWorkerNotExist(1, 1);
manager_->SharedWorkerCreated(1, 1, instance1); manager_->SharedWorkerCreated(1, 1, instance1);
CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 1, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerContextStarted(1, 1); manager_->WorkerContextStarted(1, 1);
CheckWorkerState(1, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 1, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 1); manager_->WorkerDestroyed(1, 1);
CheckWorkerNotExist(1, 1); CheckWorkerNotExist(1, 1);
// Created -> GetDevToolsAgentHost -> Started -> Destroyed // Created -> GetDevToolsAgentHost -> Started -> Destroyed
CheckWorkerNotExist(1, 2); CheckWorkerNotExist(1, 2);
manager_->SharedWorkerCreated(1, 2, instance1); manager_->SharedWorkerCreated(1, 2, instance1);
CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED);
agent_host = manager_->GetDevToolsAgentHostForWorker(1, 2); agent_host = manager_->GetDevToolsAgentHostForWorker(1, 2);
EXPECT_TRUE(agent_host.get()); EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED);
EXPECT_EQ(agent_host.get(), manager_->GetDevToolsAgentHostForWorker(1, 2)); EXPECT_EQ(agent_host.get(), manager_->GetDevToolsAgentHostForWorker(1, 2));
manager_->WorkerContextStarted(1, 2); manager_->WorkerContextStarted(1, 2);
CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(1, 2, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 2); manager_->WorkerDestroyed(1, 2);
CheckWorkerState(1, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(1, 2, WorkerState::WORKER_TERMINATED);
agent_host = NULL; agent_host = NULL;
CheckWorkerNotExist(1, 2); CheckWorkerNotExist(1, 2);
// Created -> Started -> GetDevToolsAgentHost -> Destroyed // Created -> Started -> GetDevToolsAgentHost -> Destroyed
CheckWorkerNotExist(1, 3); CheckWorkerNotExist(1, 3);
manager_->SharedWorkerCreated(1, 3, instance1); manager_->SharedWorkerCreated(1, 3, instance1);
CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerContextStarted(1, 3); manager_->WorkerContextStarted(1, 3);
CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED);
agent_host = manager_->GetDevToolsAgentHostForWorker(1, 3); agent_host = manager_->GetDevToolsAgentHostForWorker(1, 3);
EXPECT_TRUE(agent_host.get()); EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(1, 3, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 3); manager_->WorkerDestroyed(1, 3);
CheckWorkerState(1, 3, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(1, 3, WorkerState::WORKER_TERMINATED);
agent_host = NULL; agent_host = NULL;
CheckWorkerNotExist(1, 3); CheckWorkerNotExist(1, 3);
// Created -> Destroyed // Created -> Destroyed
CheckWorkerNotExist(1, 4); CheckWorkerNotExist(1, 4);
manager_->SharedWorkerCreated(1, 4, instance1); manager_->SharedWorkerCreated(1, 4, instance1);
CheckWorkerState(1, 4, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 4, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 4); manager_->WorkerDestroyed(1, 4);
CheckWorkerNotExist(1, 4); CheckWorkerNotExist(1, 4);
// Created -> GetDevToolsAgentHost -> Destroyed // Created -> GetDevToolsAgentHost -> Destroyed
CheckWorkerNotExist(1, 5); CheckWorkerNotExist(1, 5);
manager_->SharedWorkerCreated(1, 5, instance1); manager_->SharedWorkerCreated(1, 5, instance1);
CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 5, WorkerState::WORKER_UNINSPECTED);
agent_host = manager_->GetDevToolsAgentHostForWorker(1, 5); agent_host = manager_->GetDevToolsAgentHostForWorker(1, 5);
EXPECT_TRUE(agent_host.get()); EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(1, 5, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(1, 5); manager_->WorkerDestroyed(1, 5);
CheckWorkerState(1, 5, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(1, 5, WorkerState::WORKER_TERMINATED);
agent_host = NULL; agent_host = NULL;
CheckWorkerNotExist(1, 5); CheckWorkerNotExist(1, 5);
// Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed // Created -> GetDevToolsAgentHost -> Free agent_host -> Destroyed
CheckWorkerNotExist(1, 6); CheckWorkerNotExist(1, 6);
manager_->SharedWorkerCreated(1, 6, instance1); manager_->SharedWorkerCreated(1, 6, instance1);
CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(1, 6, WorkerState::WORKER_UNINSPECTED);
agent_host = manager_->GetDevToolsAgentHostForWorker(1, 6); agent_host = manager_->GetDevToolsAgentHostForWorker(1, 6);
EXPECT_TRUE(agent_host.get()); EXPECT_TRUE(agent_host.get());
CheckWorkerState(1, 6, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(1, 6, WorkerState::WORKER_UNINSPECTED);
agent_host = NULL; agent_host = NULL;
manager_->WorkerDestroyed(1, 6); manager_->WorkerDestroyed(1, 6);
CheckWorkerNotExist(1, 6); CheckWorkerNotExist(1, 6);
...@@ -199,67 +202,64 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) { ...@@ -199,67 +202,64 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
scoped_ptr<TestDevToolsClientHost> client_host1(new TestDevToolsClientHost()); scoped_ptr<TestDevToolsClientHost> client_host1(new TestDevToolsClientHost());
CheckWorkerNotExist(2, 1); CheckWorkerNotExist(2, 1);
manager_->SharedWorkerCreated(2, 1, instance1); manager_->SharedWorkerCreated(2, 1, instance1);
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(2, 1, WorkerState::WORKER_UNINSPECTED);
agent_host1 = manager_->GetDevToolsAgentHostForWorker(2, 1); agent_host1 = manager_->GetDevToolsAgentHostForWorker(2, 1);
EXPECT_TRUE(agent_host1.get()); EXPECT_TRUE(agent_host1.get());
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(2, 1, WorkerState::WORKER_UNINSPECTED);
EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1)); EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
RegisterDevToolsClientHostFor(agent_host1.get(), client_host1.get()); RegisterDevToolsClientHostFor(agent_host1.get(), client_host1.get());
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(2, 1, WorkerState::WORKER_INSPECTED);
manager_->WorkerContextStarted(2, 1); manager_->WorkerContextStarted(2, 1);
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(2, 1, WorkerState::WORKER_INSPECTED);
manager_->WorkerDestroyed(2, 1); manager_->WorkerDestroyed(2, 1);
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 1, WorkerState::WORKER_TERMINATED);
EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1)); EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 1));
// Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed // Created -> Started -> GetDevToolsAgentHost -> Register -> Destroyed
scoped_ptr<TestDevToolsClientHost> client_host2(new TestDevToolsClientHost()); scoped_ptr<TestDevToolsClientHost> client_host2(new TestDevToolsClientHost());
manager_->SharedWorkerCreated(2, 2, instance2); manager_->SharedWorkerCreated(2, 2, instance2);
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerContextStarted(2, 2); manager_->WorkerContextStarted(2, 2);
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_UNINSPECTED); CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED);
agent_host2 = manager_->GetDevToolsAgentHostForWorker(2, 2); agent_host2 = manager_->GetDevToolsAgentHostForWorker(2, 2);
EXPECT_TRUE(agent_host2.get()); EXPECT_TRUE(agent_host2.get());
EXPECT_NE(agent_host1.get(), agent_host2.get()); EXPECT_NE(agent_host1.get(), agent_host2.get());
EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2)); EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(2, 2, WorkerState::WORKER_UNINSPECTED);
RegisterDevToolsClientHostFor(agent_host2.get(), client_host2.get()); RegisterDevToolsClientHostFor(agent_host2.get(), client_host2.get());
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(2, 2, WorkerState::WORKER_INSPECTED);
manager_->WorkerDestroyed(2, 2); manager_->WorkerDestroyed(2, 2);
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 2, WorkerState::WORKER_TERMINATED);
EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2)); EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 2));
// Re-created -> Started -> ClientHostClosing -> Destroyed // Re-created -> Started -> ClientHostClosing -> Destroyed
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 1, WorkerState::WORKER_TERMINATED);
manager_->SharedWorkerCreated(2, 3, instance1); manager_->SharedWorkerCreated(2, 3, instance1);
CheckWorkerNotExist(2, 1); CheckWorkerNotExist(2, 1);
CheckWorkerState( CheckWorkerState(2, 3, WorkerState::WORKER_PAUSED_FOR_REATTACH);
2, 3, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 3)); EXPECT_EQ(agent_host1.get(), manager_->GetDevToolsAgentHostForWorker(2, 3));
manager_->WorkerContextStarted(2, 3); manager_->WorkerContextStarted(2, 3);
CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED); CheckWorkerState(2, 3, WorkerState::WORKER_INSPECTED);
ClientHostClosing(client_host1.get()); ClientHostClosing(client_host1.get());
manager_->WorkerDestroyed(2, 3); manager_->WorkerDestroyed(2, 3);
CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 3, WorkerState::WORKER_TERMINATED);
agent_host1 = NULL; agent_host1 = NULL;
CheckWorkerNotExist(2, 3); CheckWorkerNotExist(2, 3);
// Re-created -> Destroyed // Re-created -> Destroyed
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 2, WorkerState::WORKER_TERMINATED);
manager_->SharedWorkerCreated(2, 4, instance2); manager_->SharedWorkerCreated(2, 4, instance2);
CheckWorkerNotExist(2, 2); CheckWorkerNotExist(2, 2);
CheckWorkerState( CheckWorkerState(2, 4, WorkerState::WORKER_PAUSED_FOR_REATTACH);
2, 4, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 4)); EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 4));
manager_->WorkerDestroyed(2, 4); manager_->WorkerDestroyed(2, 4);
CheckWorkerNotExist(2, 4); CheckWorkerNotExist(2, 2);
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 4, WorkerState::WORKER_TERMINATED);
// Re-created -> ClientHostClosing -> Destroyed // Re-created -> ClientHostClosing -> Destroyed
manager_->SharedWorkerCreated(2, 5, instance2); manager_->SharedWorkerCreated(2, 5, instance2);
CheckWorkerNotExist(2, 2); CheckWorkerNotExist(2, 2);
CheckWorkerState( CheckWorkerState(2, 5, WorkerState::WORKER_PAUSED_FOR_REATTACH);
2, 5, EmbeddedWorkerDevToolsManager::WORKER_PAUSED_FOR_REATTACH);
EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 5)); EXPECT_EQ(agent_host2.get(), manager_->GetDevToolsAgentHostForWorker(2, 5));
ClientHostClosing(client_host2.get()); ClientHostClosing(client_host2.get());
CheckWorkerCount(1); CheckWorkerCount(1);
...@@ -269,4 +269,35 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) { ...@@ -269,4 +269,35 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
CheckWorkerCount(0); CheckWorkerCount(0);
} }
TEST_F(EmbeddedWorkerDevToolsManagerTest, ReattachTest) {
SharedWorkerInstance instance(GURL("http://example.com/w3.js"),
base::string16(),
base::string16(),
blink::WebContentSecurityPolicyTypeReport,
browser_context_->GetResourceContext(),
partition_id_);
scoped_ptr<TestDevToolsClientHost> client_host(new TestDevToolsClientHost());
// Created -> GetDevToolsAgentHost -> Register -> Destroyed
manager_->SharedWorkerCreated(3, 1, instance);
CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED);
scoped_refptr<DevToolsAgentHost> agent_host(
manager_->GetDevToolsAgentHostForWorker(3, 1));
EXPECT_TRUE(agent_host.get());
CheckWorkerState(3, 1, WorkerState::WORKER_UNINSPECTED);
RegisterDevToolsClientHostFor(agent_host.get(), client_host.get());
CheckWorkerState(3, 1, WorkerState::WORKER_INSPECTED);
manager_->WorkerDestroyed(3, 1);
CheckWorkerState(3, 1, WorkerState::WORKER_TERMINATED);
// ClientHostClosing -> Re-created -> release agent_host -> Destroyed
ClientHostClosing(client_host.get());
CheckWorkerState(3, 1, WorkerState::WORKER_TERMINATED);
manager_->SharedWorkerCreated(3, 2, instance);
CheckWorkerState(3, 2, WorkerState::WORKER_UNINSPECTED);
agent_host = NULL;
CheckWorkerState(3, 2, WorkerState::WORKER_UNINSPECTED);
manager_->WorkerDestroyed(3, 2);
CheckWorkerNotExist(3, 2);
CheckWorkerCount(0);
}
} // namespace content } // namespace content
...@@ -443,6 +443,8 @@ ...@@ -443,6 +443,8 @@
'browser/devtools/forwarding_agent_host.h', 'browser/devtools/forwarding_agent_host.h',
'browser/devtools/ipc_devtools_agent_host.cc', 'browser/devtools/ipc_devtools_agent_host.cc',
'browser/devtools/ipc_devtools_agent_host.h', 'browser/devtools/ipc_devtools_agent_host.h',
'browser/devtools/embedded_worker_devtools_agent_host.cc',
'browser/devtools/embedded_worker_devtools_agent_host.h',
'browser/devtools/embedded_worker_devtools_manager.cc', 'browser/devtools/embedded_worker_devtools_manager.cc',
'browser/devtools/embedded_worker_devtools_manager.h', 'browser/devtools/embedded_worker_devtools_manager.h',
'browser/devtools/render_view_devtools_agent_host.cc', 'browser/devtools/render_view_devtools_agent_host.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment