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(
return NULL;
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();
}
EmbeddedWorkerDevToolsAgentHost* agent_host =
new EmbeddedWorkerDevToolsAgentHost(id);
......@@ -197,7 +199,8 @@ EmbeddedWorkerDevToolsManager::GetDevToolsAgentHostForServiceWorker(
return GetDevToolsAgentHostForWorker(it->first.first, it->first.second);
}
EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager() {
EmbeddedWorkerDevToolsManager::EmbeddedWorkerDevToolsManager()
: debug_service_worker_on_start_(false) {
}
EmbeddedWorkerDevToolsManager::~EmbeddedWorkerDevToolsManager() {
......@@ -228,8 +231,10 @@ bool EmbeddedWorkerDevToolsManager::ServiceWorkerCreated(
WorkerInfoMap::iterator it = FindExistingServiceWorkerInfo(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());
return false;
return debug_service_worker_on_start_;
}
MoveToPausedState(id, it);
return true;
......@@ -244,6 +249,7 @@ void EmbeddedWorkerDevToolsManager::WorkerDestroyed(int worker_process_id,
WorkerInfo* info = it->second;
switch (info->state()) {
case WORKER_UNINSPECTED:
case WORKER_PAUSED_FOR_DEBUG_ON_START:
workers_.erase(it);
break;
case WORKER_INSPECTED: {
......@@ -267,7 +273,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,10 +290,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)
return;
info->agent_host()->ReattachToWorker(id);
info->set_state(WORKER_INSPECTED);
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(
......@@ -302,7 +314,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 +352,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());
}
......
......@@ -50,17 +50,27 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
DevToolsAgentHost* GetDevToolsAgentHostForServiceWorker(
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,
int worker_route_id,
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,
int worker_route_id,
const ServiceWorkerIdentifier& service_worker_id);
void WorkerContextStarted(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:
friend struct DefaultSingletonTraits<EmbeddedWorkerDevToolsManager>;
friend class EmbeddedWorkerDevToolsManagerTest;
......@@ -71,7 +81,8 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
WORKER_UNINSPECTED,
WORKER_INSPECTED,
WORKER_TERMINATED,
WORKER_PAUSED,
WORKER_PAUSED_FOR_DEBUG_ON_START,
WORKER_PAUSED_FOR_REATTACH,
};
class WorkerInfo {
......@@ -117,6 +128,8 @@ class CONTENT_EXPORT EmbeddedWorkerDevToolsManager {
WorkerInfoMap workers_;
bool debug_service_worker_on_start_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerDevToolsManager);
};
......
......@@ -230,7 +230,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
CheckWorkerState(2, 1, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
manager_->SharedWorkerCreated(2, 3, instance1);
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));
manager_->WorkerContextStarted(2, 3);
CheckWorkerState(2, 3, EmbeddedWorkerDevToolsManager::WORKER_INSPECTED);
......@@ -243,7 +244,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
CheckWorkerState(2, 2, EmbeddedWorkerDevToolsManager::WORKER_TERMINATED);
manager_->SharedWorkerCreated(2, 4, instance2);
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));
manager_->WorkerDestroyed(2, 4);
CheckWorkerNotExist(2, 4);
......@@ -252,7 +254,8 @@ TEST_F(EmbeddedWorkerDevToolsManagerTest, AttachTest) {
// Re-created -> ClientHostClosing -> Destroyed
manager_->SharedWorkerCreated(2, 5, instance2);
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));
ClientHostClosing(client_host2.get());
CheckWorkerCount(1);
......
......@@ -99,9 +99,18 @@
<div transclude="serviceworker-version-template"></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>
<h1>ServiceWorker registrations</h1>
<h1>ServiceWorker</h1>
<div class="content">
<div id="serviceworker-options"></div>
<div id="serviceworker-list"></div>
</div>
<script src="chrome://resources/js/util.js"></script>
......
......@@ -21,7 +21,31 @@ cr.define('serviceworker', function() {
}
function update() {
chrome.send('getAllRegistrations');
chrome.send('GetOptions');
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) {
......@@ -264,6 +288,7 @@ cr.define('serviceworker', function() {
return {
initialize: initialize,
onOptions: onOptions,
onOperationComplete: onOperationComplete,
onPartitionData: onPartitionData,
onWorkerStarted: onWorkerStarted,
......
......@@ -378,6 +378,13 @@ ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI* web_ui)
web_ui->GetWebContents()->GetBrowserContext();
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(
"getAllRegistrations",
base::Bind(&ServiceWorkerInternalsUI::GetAllRegistrations,
......@@ -417,6 +424,25 @@ ServiceWorkerInternalsUI::~ServiceWorkerInternalsUI() {
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) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
BrowserContext* browser_context =
......
......@@ -48,6 +48,8 @@ class ServiceWorkerInternalsUI
void RemoveObserverFromStoragePartition(StoragePartition* partition);
// Called from Javascript.
void GetOptions(const base::ListValue* args);
void SetOption(const base::ListValue* args);
void GetAllRegistrations(const base::ListValue* args);
void CallServiceWorkerVersionMethod(ServiceWorkerVersionMethod method,
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