Commit 2b19d7ae authored by horo@google.com's avatar horo@google.com

Add option to open the DevTools window for ServiceWorker on start in serviceworker-internals.

BUG=358657
R=yurys@chromium.org
TBR=pfeldman@chromium.org

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273761 0039d316-1c4b-4281-b951-d872f2087c98
parent 69871da3
...@@ -178,8 +178,10 @@ DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker( ...@@ -178,8 +178,10 @@ DevToolsAgentHost* EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForWorker(
return NULL; return NULL;
WorkerInfo* info = it->second; WorkerInfo* info = it->second;
if (info->state() != WORKER_UNINSPECTED) if (info->state() != WORKER_UNINSPECTED &&
info->state() != WORKER_PAUSED_FOR_DEBUG_ON_START) {
return info->agent_host(); return info->agent_host();
}
EmbeddedWorkerDevToolsAgentHost* agent_host = EmbeddedWorkerDevToolsAgentHost* agent_host =
new EmbeddedWorkerDevToolsAgentHost(id); new EmbeddedWorkerDevToolsAgentHost(id);
...@@ -197,7 +199,8 @@ EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker( ...@@ -197,7 +199,8 @@ EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker(
return GetDevToolsAgentHostForWorker(it->first.first, it->first.second); return GetDevToolsAgentHostForWorker(it->first.first, it->first.second);
} }
EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() { EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager()
: debug_service_worker_on_start_(false) {
} }
EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() { EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() {
...@@ -228,8 +231,10 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated( ...@@ -228,8 +231,10 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated(
WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id); WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(service_worker_id);
if (it == workers_.end()) { if (it == workers_.end()) {
scoped_ptr<WorkerInfo> info(new WorkerInfo(service_worker_id)); 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_.set(id, info.Pass());
return false; return debug_service_worker_on_start_;
} }
MoveToPausedState(id, it); MoveToPausedState(id, it);
return true; return true;
...@@ -244,6 +249,7 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id, ...@@ -244,6 +249,7 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
WorkerInfo* info = it->second; WorkerInfo* info = it->second;
switch (info->state()) { switch (info->state()) {
case WORKER_UNINSPECTED: case WORKER_UNINSPECTED:
case WORKER_PAUSED_FOR_DEBUG_ON_START:
workers_.erase(it); workers_.erase(it);
break; break;
case WORKER_INSPECTED: { case WORKER_INSPECTED: {
...@@ -267,7 +273,7 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id, ...@@ -267,7 +273,7 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
case WORKER_TERMINATED: case WORKER_TERMINATED:
NOTREACHED(); NOTREACHED();
break; break;
case WORKER_PAUSED: { case WORKER_PAUSED_FOR_REATTACH: {
scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it); scoped_ptr<WorkerInfo> worker_info = workers_.take_and_erase(it);
worker_info->set_state(WORKER_TERMINATED); worker_info->set_state(WORKER_TERMINATED);
const WorkerId old_id = worker_info->agent_host()->worker_id(); const WorkerId old_id = worker_info->agent_host()->worker_id();
...@@ -284,10 +290,16 @@ void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id, ...@@ -284,10 +290,16 @@ void EmbeddedWorkerDevToolsManager::WorkerContextStarted(int worker_process_id,
WorkerInfoMap::iterator it = workers_.find(id); WorkerInfoMap::iterator it = workers_.find(id);
DCHECK(it != workers_.end()); DCHECK(it != workers_.end());
WorkerInfo* info = it->second; WorkerInfo* info = it->second;
if (info->state() != WORKER_PAUSED) if (info->state() == WORKER_PAUSED_FOR_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());
} else if (info->state() == WORKER_PAUSED_FOR_REATTACH) {
info->agent_host()->ReattachToWorker(id); info->agent_host()->ReattachToWorker(id);
info->set_state(WORKER_INSPECTED); info->set_state(WORKER_INSPECTED);
}
} }
void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData( void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(
...@@ -302,7 +314,7 @@ void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData( ...@@ -302,7 +314,7 @@ void EmbeddedWorkerDevToolsManager::RemoveInspectedWorkerData(
for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end(); for (WorkerInfoMap::iterator it = workers_.begin(); it != workers_.end();
++it) { ++it) {
if (it->second->agent_host() == agent_host) { if (it->second->agent_host() == agent_host) {
DCHECK_EQ(WORKER_PAUSED, it->second->state()); DCHECK_EQ(WORKER_PAUSED_FOR_REATTACH, it->second->state());
SendMessageToWorker( SendMessageToWorker(
it->first, it->first,
new DevToolsAgentMsg_ResumeWorkerContext(it->first.second)); new DevToolsAgentMsg_ResumeWorkerContext(it->first.second));
...@@ -340,7 +352,7 @@ void EmbeddedWorkerDevToolsManager::MoveToPausedState( ...@@ -340,7 +352,7 @@ void EmbeddedWorkerDevToolsManager::MoveToPausedState(
const WorkerInfoMap::iterator& it) { const WorkerInfoMap::iterator& it) {
DCHECK_EQ(WORKER_TERMINATED, it->second->state()); DCHECK_EQ(WORKER_TERMINATED, it->second->state());
scoped_ptr<WorkerInfo> info = workers_.take_and_erase(it); 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()); workers_.set(id, info.Pass());
} }
......
...@@ -50,17 +50,27 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager { ...@@ -50,17 +50,27 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
DevToolsAgentHost* GetDevToolsAgentHostForServiceWorker( DevToolsAgentHost* GetDevToolsAgentHostForServiceWorker(
const ServiceWorkerIdentifier& service_worker_id); const ServiceWorkerIdentifier& service_worker_id);
// Returns true when the worker must be paused on start. // Returns true when the worker must be paused on start because a DevTool
// window for the same former SharedWorkerInstance is still opened.
bool SharedWorkerCreated(int worker_process_id, bool SharedWorkerCreated(int worker_process_id,
int worker_route_id, int worker_route_id,
const SharedWorkerInstance& instance); const SharedWorkerInstance& instance);
// Returns true when the worker must be paused on start. // Returns true when the worker must be paused on start because a DevTool
// window for the same former ServiceWorkerIdentifier is still opened or
// debug-on-start is enabled in chrome://serviceworker-internals.
bool ServiceWorkerCreated(int worker_process_id, bool ServiceWorkerCreated(int worker_process_id,
int worker_route_id, int worker_route_id,
const ServiceWorkerIdentifier& service_worker_id); const ServiceWorkerIdentifier& service_worker_id);
void WorkerContextStarted(int worker_process_id, int worker_route_id); void WorkerContextStarted(int worker_process_id, int worker_route_id);
void WorkerDestroyed(int worker_process_id, int worker_route_id); void WorkerDestroyed(int worker_process_id, int worker_route_id);
void set_debug_service_worker_on_start(bool debug_on_start) {
debug_service_worker_on_start_ = debug_on_start;
}
bool debug_service_worker_on_start() const {
return debug_service_worker_on_start_;
}
private: private:
friend struct DefaultSingletonTraits<EmbeddedWorkerDevToolsManager>; friend struct DefaultSingletonTraits<EmbeddedWorkerDevToolsManager>;
friend class EmbeddedWorkerDevToolsManagerTest; friend class EmbeddedWorkerDevToolsManagerTest;
...@@ -71,7 +81,8 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager { ...@@ -71,7 +81,8 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
WORKER_UNINSPECTED, WORKER_UNINSPECTED,
WORKER_INSPECTED, WORKER_INSPECTED,
WORKER_TERMINATED, WORKER_TERMINATED,
WORKER_PAUSED, WORKER_PAUSED_FOR_DEBUG_ON_START,
WORKER_PAUSED_FOR_REATTACH,
}; };
class WorkerInfo { class WorkerInfo {
...@@ -117,6 +128,8 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager { ...@@ -117,6 +128,8 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
WorkerInfoMap workers_; WorkerInfoMap workers_;
bool debug_service_worker_on_start_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsManager); DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsManager);
}; };
......
...@@ -230,7 +230,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) { ...@@ -230,7 +230,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
manager_->SharedWorkerCreated(2, 3, instance1); manager_->SharedWorkerCreated(2, 3, instance1);
CheckWorkerNotExist(2, 1); CheckWorkerNotExist(2, 1);
CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_PAUSED); CheckWorkerState(
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, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
...@@ -243,7 +244,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) { ...@@ -243,7 +244,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED); CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
manager_->SharedWorkerCreated(2, 4, instance2); manager_->SharedWorkerCreated(2, 4, instance2);
CheckWorkerNotExist(2, 2); CheckWorkerNotExist(2, 2);
CheckWorkerState(2, 4, EmbeddedWorkerDevToolsManager::WORKER_PAUSED); CheckWorkerState(
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, 4);
...@@ -252,7 +254,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) { ...@@ -252,7 +254,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
// 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(2, 5, EmbeddedWorkerDevToolsManager::WORKER_PAUSED); CheckWorkerState(
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);
......
...@@ -99,9 +99,18 @@ ...@@ -99,9 +99,18 @@
<div transclude="serviceworker-version-template"></div> <div transclude="serviceworker-version-template"></div>
</div> </div>
</div> </div>
<div id="serviceworker-options-template">
<div>
<span>
<input type="checkbox" class="debug_on_start" jsvalues=".checked:$this.debug_on_start">
</span>
<span>Opens the DevTools window for ServiceWorker on start for debugging.</span>
</div>
</div>
</div> </div>
<h1>ServiceWorker registrations</h1> <h1>ServiceWorker</h1>
<div class="content"> <div class="content">
<div id="serviceworker-options"></div>
<div id="serviceworker-list"></div> <div id="serviceworker-list"></div>
</div> </div>
<script src="chrome://resources/js/util.js"></script> <script src="chrome://resources/js/util.js"></script>
......
...@@ -21,9 +21,33 @@ cr.define('serviceworker', function() { ...@@ -21,9 +21,33 @@ cr.define('serviceworker', function() {
} }
function update() { function update() {
chrome.send('GetOptions');
chrome.send('getAllRegistrations'); chrome.send('getAllRegistrations');
} }
function onOptions(options) {
var template;
var container = $('serviceworker-options');
if (container.childNodes) {
template = container.childNodes[0];
}
if (!template) {
template = jstGetTemplate('serviceworker-options-template');
container.appendChild(template);
}
jstProcess(new JsEvalContext(options), template);
var inputs = container.querySelectorAll('input[type=\'checkbox\']');
for (var i = 0; i < inputs.length; ++i) {
if (!inputs[i].hasClickEvent) {
inputs[i].addEventListener('click', (function(event) {
chrome.send('SetOption',
[event.target.className, event.target.checked]);
}).bind(this), false);
inputs[i].hasClickEvent = true;
}
}
}
function progressNodeFor(link) { function progressNodeFor(link) {
return link.parentNode.querySelector('.operation-status'); return link.parentNode.querySelector('.operation-status');
} }
...@@ -264,6 +288,7 @@ cr.define('serviceworker', function() { ...@@ -264,6 +288,7 @@ cr.define('serviceworker', function() {
return { return {
initialize: initialize, initialize: initialize,
onOptions: onOptions,
onOperationComplete: onOperationComplete, onOperationComplete: onOperationComplete,
onPartitionData: onPartitionData, onPartitionData: onPartitionData,
onWorkerStarted: onWorkerStarted, onWorkerStarted: onWorkerStarted,
......
...@@ -378,6 +378,13 @@ ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI* web_ui) ...@@ -378,6 +378,13 @@ ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI* web_ui)
web_ui->GetWebContents()->GetBrowserContext(); web_ui->GetWebContents()->GetBrowserContext();
WebUIDataSource::Add(browser_context, source); WebUIDataSource::Add(browser_context, source);
web_ui->RegisterMessageCallback(
"GetOptions",
base::Bind(&ServiceWorkerInternalsUI::GetOptions,
base::Unretained(this)));
web_ui->RegisterMessageCallback(
"SetOption",
base::Bind(&ServiceWorkerInternalsUI::SetOption, base::Unretained(this)));
web_ui->RegisterMessageCallback( web_ui->RegisterMessageCallback(
"getAllRegistrations", "getAllRegistrations",
base::Bind(&ServiceWorkerInternalsUI::GetAllRegistrations, base::Bind(&ServiceWorkerInternalsUI::GetAllRegistrations,
...@@ -417,6 +424,25 @@ ServiceWorkerInternalsUI::~ServiceWorkerInternalsUI() { ...@@ -417,6 +424,25 @@ ServiceWorkerInternalsUI::~ServiceWorkerInternalsUI() {
BrowserContext::ForEachStoragePartition(browser_context, remove_observer_cb); BrowserContext::ForEachStoragePartition(browser_context, remove_observer_cb);
} }
void ServiceWorkerInternalsUI::GetOptions(const ListValue* args) {
DictionaryValue options;
options.SetBoolean("debug_on_start",
EmbeddedWorkerDevToolsManager::GetInstance()
->debug_service_worker_on_start());
web_ui()->CallJavascriptFunction("serviceworker.onOptions", options);
}
void ServiceWorkerInternalsUI::SetOption(const ListValue* args) {
std::string option_name;
bool option_boolean;
if (!args->GetString(0, &option_name) || option_name != "debug_on_start" ||
!args->GetBoolean(1, &option_boolean)) {
return;
}
EmbeddedWorkerDevToolsManager::GetInstance()
->set_debug_service_worker_on_start(option_boolean);
}
void ServiceWorkerInternalsUI::GetAllRegistrations(const ListValue* args) { void ServiceWorkerInternalsUI::GetAllRegistrations(const ListValue* args) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
BrowserContext* browser_context = BrowserContext* browser_context =
......
...@@ -48,6 +48,8 @@ class ServiceWorkerInternalsUI ...@@ -48,6 +48,8 @@ class ServiceWorkerInternalsUI
void RemoveObserverFromStoragePartition(StoragePartition* partition); void RemoveObserverFromStoragePartition(StoragePartition* partition);
// Called from Javascript. // Called from Javascript.
void GetOptions(const base::ListValue* args);
void SetOption(const base::ListValue* args);
void GetAllRegistrations(const base::ListValue* args); void GetAllRegistrations(const base::ListValue* args);
void CallServiceWorkerVersionMethod(ServiceWorkerVersionMethod method, void CallServiceWorkerVersionMethod(ServiceWorkerVersionMethod method,
const base::ListValue* args); const base::ListValue* args);
......
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