Commit 850e832d authored by nhiroki's avatar nhiroki Committed by Commit bot

ServiceWorker: Queue tasks until the registration proxy becomes ready

In [[Install]] algo. of the latest spec, register() resolves a promise
with a registration object after the worker enters the installation
process. This means the registration needs to set its .installing field
before the register promise is resolved.

But, before this patch, the registration cannot do so before resolving
the register promise because its proxy is set when the registration is
passed to the blink.

This change makes the registration queue notifications of worker version
and 'updatefound'. Once the proxy becomes ready, the registration handles
them.

Spec: https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#installation-algorithm

BUG=399533,406240
TEST=content_unittests --gtest_filter=ServiceWorker*
TEST=run_webkit_tests.py http/tests/serviceworker

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

Cr-Commit-Position: refs/heads/master@{#292535}
parent d3106c04
...@@ -6,11 +6,19 @@ ...@@ -6,11 +6,19 @@
#include "content/child/service_worker/service_worker_dispatcher.h" #include "content/child/service_worker/service_worker_dispatcher.h"
#include "content/child/service_worker/service_worker_registration_handle_reference.h" #include "content/child/service_worker/service_worker_registration_handle_reference.h"
#include "content/child/service_worker/web_service_worker_impl.h"
#include "content/common/service_worker/service_worker_types.h" #include "content/common/service_worker/service_worker_types.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerRegistrationProxy.h" #include "third_party/WebKit/public/platform/WebServiceWorkerRegistrationProxy.h"
namespace content { namespace content {
WebServiceWorkerRegistrationImpl::QueuedTask::QueuedTask(
QueuedTaskType type,
blink::WebServiceWorker* worker)
: type(type),
worker(worker) {
}
WebServiceWorkerRegistrationImpl::WebServiceWorkerRegistrationImpl( WebServiceWorkerRegistrationImpl::WebServiceWorkerRegistrationImpl(
scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref) scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref)
: handle_ref_(handle_ref.Pass()), : handle_ref_(handle_ref.Pass()),
...@@ -29,34 +37,70 @@ WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() { ...@@ -29,34 +37,70 @@ WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() {
ServiceWorkerDispatcher::GetThreadSpecificInstance(); ServiceWorkerDispatcher::GetThreadSpecificInstance();
if (dispatcher) if (dispatcher)
dispatcher->RemoveServiceWorkerRegistration(handle_ref_->handle_id()); dispatcher->RemoveServiceWorkerRegistration(handle_ref_->handle_id());
ClearQueuedTasks();
} }
void WebServiceWorkerRegistrationImpl::SetInstalling( void WebServiceWorkerRegistrationImpl::SetInstalling(
blink::WebServiceWorker* service_worker) { blink::WebServiceWorker* service_worker) {
DCHECK(proxy_); if (proxy_)
proxy_->setInstalling(service_worker); proxy_->setInstalling(service_worker);
else
queued_tasks_.push_back(QueuedTask(INSTALLING, service_worker));
} }
void WebServiceWorkerRegistrationImpl::SetWaiting( void WebServiceWorkerRegistrationImpl::SetWaiting(
blink::WebServiceWorker* service_worker) { blink::WebServiceWorker* service_worker) {
DCHECK(proxy_); if (proxy_)
proxy_->setWaiting(service_worker); proxy_->setWaiting(service_worker);
else
queued_tasks_.push_back(QueuedTask(WAITING, service_worker));
} }
void WebServiceWorkerRegistrationImpl::SetActive( void WebServiceWorkerRegistrationImpl::SetActive(
blink::WebServiceWorker* service_worker) { blink::WebServiceWorker* service_worker) {
DCHECK(proxy_); if (proxy_)
proxy_->setActive(service_worker); proxy_->setActive(service_worker);
else
queued_tasks_.push_back(QueuedTask(ACTIVE, service_worker));
} }
void WebServiceWorkerRegistrationImpl::OnUpdateFound() { void WebServiceWorkerRegistrationImpl::OnUpdateFound() {
DCHECK(proxy_); if (proxy_)
proxy_->dispatchUpdateFoundEvent(); proxy_->dispatchUpdateFoundEvent();
else
queued_tasks_.push_back(QueuedTask(UPDATE_FOUND, NULL));
} }
void WebServiceWorkerRegistrationImpl::setProxy( void WebServiceWorkerRegistrationImpl::setProxy(
blink::WebServiceWorkerRegistrationProxy* proxy) { blink::WebServiceWorkerRegistrationProxy* proxy) {
proxy_ = proxy; proxy_ = proxy;
RunQueuedTasks();
}
void WebServiceWorkerRegistrationImpl::RunQueuedTasks() {
DCHECK(proxy_);
for (std::vector<QueuedTask>::const_iterator it = queued_tasks_.begin();
it != queued_tasks_.end(); ++it) {
if (it->type == INSTALLING)
proxy_->setInstalling(it->worker);
else if (it->type == WAITING)
proxy_->setWaiting(it->worker);
else if (it->type == ACTIVE)
proxy_->setActive(it->worker);
else if (it->type == UPDATE_FOUND)
proxy_->dispatchUpdateFoundEvent();
}
queued_tasks_.clear();
}
void WebServiceWorkerRegistrationImpl::ClearQueuedTasks() {
for (std::vector<QueuedTask>::const_iterator it = queued_tasks_.begin();
it != queued_tasks_.end(); ++it) {
// If the owner of the WebServiceWorker does not exist, delete it.
if (it->worker && !it->worker->proxy())
delete it->worker;
}
queued_tasks_.clear();
} }
blink::WebServiceWorkerRegistrationProxy* blink::WebServiceWorkerRegistrationProxy*
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_ #ifndef CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
#define CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_ #define CONTENT_CHILD_SERVICE_WORKER_WEB_SERVICE_WORKER_REGISTRATION_IMPL_H_
#include <vector>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerRegistration.h" #include "third_party/WebKit/public/platform/WebServiceWorkerRegistration.h"
...@@ -38,9 +40,28 @@ class WebServiceWorkerRegistrationImpl ...@@ -38,9 +40,28 @@ class WebServiceWorkerRegistrationImpl
virtual blink::WebURL scope() const; virtual blink::WebURL scope() const;
private: private:
enum QueuedTaskType {
INSTALLING,
WAITING,
ACTIVE,
UPDATE_FOUND,
};
struct QueuedTask {
QueuedTask(QueuedTaskType type,
blink::WebServiceWorker* worker);
QueuedTaskType type;
blink::WebServiceWorker* worker;
};
void RunQueuedTasks();
void ClearQueuedTasks();
scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref_; scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref_;
blink::WebServiceWorkerRegistrationProxy* proxy_; blink::WebServiceWorkerRegistrationProxy* proxy_;
std::vector<QueuedTask> queued_tasks_;
DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerRegistrationImpl); DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerRegistrationImpl);
}; };
......
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