Commit 71840871 authored by nhiroki's avatar nhiroki Committed by Commit bot

ServiceWorker: Make '.ready' return a promise to be resolved with ServiceWorkerRegistration (2/3)

Potential controllees need to observe version change events to make a ready
registration, but, before this patch, those events are sent not to potential
controllees but to pages that have the corresponding registration object
(to be more precise, pages that have the reference to the registration).

After this patch, ServiceWorkerProviderHost sends an IPC message to the
corresponding ServiceWorkerProviderContext when the host gets associated with
a registration and the provider context retains a reference of the registration
so that the potential controllee can observe the version change events.

1) Blink: https://codereview.chromium.org/476043002/
2) Chromium: THIS PATCH
3) Blink: https://codereview.chromium.org/532653002/

BUG=399533
TEST=content_unittests --gtest_filter=ServiceWorker*
TEST=run_webkit_tests.py --debug http/tests/serviceworker/ (with the patch (3))

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

Cr-Commit-Position: refs/heads/master@{#294147}
parent abd0e10a
...@@ -114,7 +114,7 @@ void ServiceWorkerControlleeRequestHandler::PrepareForMainResource( ...@@ -114,7 +114,7 @@ void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
"URL", url.spec()); "URL", url.spec());
// The corresponding provider_host may already have associated a registration // The corresponding provider_host may already have associated a registration
// in redirect case, unassociate it now. // in redirect case, unassociate it now.
provider_host_->UnassociateRegistration(); provider_host_->DisassociateRegistration();
GURL stripped_url = net::SimplifyUrlForRequest(url); GURL stripped_url = net::SimplifyUrlForRequest(url);
provider_host_->SetDocumentUrl(stripped_url); provider_host_->SetDocumentUrl(stripped_url);
......
...@@ -60,7 +60,7 @@ void ServiceWorkerProviderHost::OnVersionAttributesChanged( ...@@ -60,7 +60,7 @@ void ServiceWorkerProviderHost::OnVersionAttributesChanged(
void ServiceWorkerProviderHost::OnRegistrationFailed( void ServiceWorkerProviderHost::OnRegistrationFailed(
ServiceWorkerRegistration* registration) { ServiceWorkerRegistration* registration) {
DCHECK_EQ(associated_registration_.get(), registration); DCHECK_EQ(associated_registration_.get(), registration);
UnassociateRegistration(); DisassociateRegistration();
} }
void ServiceWorkerProviderHost::SetDocumentUrl(const GURL& url) { void ServiceWorkerProviderHost::SetDocumentUrl(const GURL& url) {
...@@ -116,15 +116,32 @@ void ServiceWorkerProviderHost::AssociateRegistration( ...@@ -116,15 +116,32 @@ void ServiceWorkerProviderHost::AssociateRegistration(
DecreaseProcessReference(associated_registration_->pattern()); DecreaseProcessReference(associated_registration_->pattern());
IncreaseProcessReference(registration->pattern()); IncreaseProcessReference(registration->pattern());
if (dispatcher_host_) {
ServiceWorkerRegistrationHandle* handle =
dispatcher_host_->GetOrCreateRegistrationHandle(
provider_id(), registration);
ServiceWorkerVersionAttributes attrs;
attrs.installing = handle->CreateServiceWorkerHandleAndPass(
registration->installing_version());
attrs.waiting = handle->CreateServiceWorkerHandleAndPass(
registration->waiting_version());
attrs.active = handle->CreateServiceWorkerHandleAndPass(
registration->active_version());
dispatcher_host_->Send(new ServiceWorkerMsg_AssociateRegistration(
kDocumentMainThreadId, provider_id(), handle->GetObjectInfo(), attrs));
}
associated_registration_ = registration; associated_registration_ = registration;
registration->AddListener(this); associated_registration_->AddListener(this);
installing_version_ = registration->installing_version(); installing_version_ = registration->installing_version();
waiting_version_ = registration->waiting_version(); waiting_version_ = registration->waiting_version();
active_version_ = registration->active_version(); active_version_ = registration->active_version();
SetControllerVersionAttribute(registration->active_version()); SetControllerVersionAttribute(registration->active_version());
} }
void ServiceWorkerProviderHost::UnassociateRegistration() { void ServiceWorkerProviderHost::DisassociateRegistration() {
if (!associated_registration_.get()) if (!associated_registration_.get())
return; return;
DecreaseProcessReference(associated_registration_->pattern()); DecreaseProcessReference(associated_registration_->pattern());
...@@ -134,6 +151,11 @@ void ServiceWorkerProviderHost::UnassociateRegistration() { ...@@ -134,6 +151,11 @@ void ServiceWorkerProviderHost::UnassociateRegistration() {
waiting_version_ = NULL; waiting_version_ = NULL;
active_version_ = NULL; active_version_ = NULL;
SetControllerVersionAttribute(NULL); SetControllerVersionAttribute(NULL);
if (dispatcher_host_) {
dispatcher_host_->Send(new ServiceWorkerMsg_DisassociateRegistration(
kDocumentMainThreadId, provider_id()));
}
} }
scoped_ptr<ServiceWorkerRequestHandler> scoped_ptr<ServiceWorkerRequestHandler>
......
...@@ -83,7 +83,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost ...@@ -83,7 +83,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
void AssociateRegistration(ServiceWorkerRegistration* registration); void AssociateRegistration(ServiceWorkerRegistration* registration);
// Clears the associated registration and stop listening to it. // Clears the associated registration and stop listening to it.
void UnassociateRegistration(); void DisassociateRegistration();
// Returns false if the version is not in the expected STARTING in our // Returns false if the version is not in the expected STARTING in our
// process state. That would be indicative of a bad IPC message. // process state. That would be indicative of a bad IPC message.
......
...@@ -97,7 +97,7 @@ TEST_F(ServiceWorkerProviderHostTest, SetActiveVersion_ProcessStatus) { ...@@ -97,7 +97,7 @@ TEST_F(ServiceWorkerProviderHostTest, SetActiveVersion_ProcessStatus) {
// Resetting the provider_host's active version should remove process refs // Resetting the provider_host's active version should remove process refs
// from the version. // from the version.
provider_host1_->UnassociateRegistration(); provider_host1_->DisassociateRegistration();
ASSERT_FALSE(HasProcessToRun()); ASSERT_FALSE(HasProcessToRun());
} }
...@@ -113,11 +113,11 @@ TEST_F(ServiceWorkerProviderHostTest, ...@@ -113,11 +113,11 @@ TEST_F(ServiceWorkerProviderHostTest,
// Disassociating one provider_host shouldn't remove all process refs // Disassociating one provider_host shouldn't remove all process refs
// from the version yet. // from the version yet.
provider_host1_->UnassociateRegistration(); provider_host1_->DisassociateRegistration();
ASSERT_TRUE(HasProcessToRun()); ASSERT_TRUE(HasProcessToRun());
// Disassociating the other provider_host will remove all process refs. // Disassociating the other provider_host will remove all process refs.
provider_host2_->UnassociateRegistration(); provider_host2_->DisassociateRegistration();
ASSERT_FALSE(HasProcessToRun()); ASSERT_FALSE(HasProcessToRun());
} }
...@@ -136,7 +136,7 @@ TEST_F(ServiceWorkerProviderHostTest, SetWaitingVersion_ProcessStatus) { ...@@ -136,7 +136,7 @@ TEST_F(ServiceWorkerProviderHostTest, SetWaitingVersion_ProcessStatus) {
// Resetting the provider_host's waiting version should remove process refs // Resetting the provider_host's waiting version should remove process refs
// from the version. // from the version.
provider_host1_->UnassociateRegistration(); provider_host1_->DisassociateRegistration();
ASSERT_FALSE(HasProcessToRun()); ASSERT_FALSE(HasProcessToRun());
} }
...@@ -152,11 +152,11 @@ TEST_F(ServiceWorkerProviderHostTest, ...@@ -152,11 +152,11 @@ TEST_F(ServiceWorkerProviderHostTest,
// Disassociating one provider_host shouldn't remove all process refs // Disassociating one provider_host shouldn't remove all process refs
// from the version yet. // from the version yet.
provider_host1_->UnassociateRegistration(); provider_host1_->DisassociateRegistration();
ASSERT_TRUE(HasProcessToRun()); ASSERT_TRUE(HasProcessToRun());
// Disassociating the other provider_host will remove all process refs. // Disassociating the other provider_host will remove all process refs.
provider_host2_->UnassociateRegistration(); provider_host2_->DisassociateRegistration();
ASSERT_FALSE(HasProcessToRun()); ASSERT_FALSE(HasProcessToRun());
} }
...@@ -176,7 +176,7 @@ TEST_F(ServiceWorkerProviderHostTest, ...@@ -176,7 +176,7 @@ TEST_F(ServiceWorkerProviderHostTest,
VerifyVersionAttributes(provider_host2_, NULL, version_.get(), NULL); VerifyVersionAttributes(provider_host2_, NULL, version_.get(), NULL);
// Disassociating the registration should clear all version attributes. // Disassociating the registration should clear all version attributes.
provider_host2_->UnassociateRegistration(); provider_host2_->DisassociateRegistration();
VerifyVersionAttributes(provider_host1_, NULL, version_.get(), NULL); VerifyVersionAttributes(provider_host1_, NULL, version_.get(), NULL);
VerifyVersionAttributes(provider_host2_, NULL, NULL, NULL); VerifyVersionAttributes(provider_host2_, NULL, NULL, NULL);
...@@ -213,7 +213,7 @@ TEST_F(ServiceWorkerProviderHostTest, ...@@ -213,7 +213,7 @@ TEST_F(ServiceWorkerProviderHostTest,
provider_host2_, version2.get(), version1.get(), NULL); provider_host2_, version2.get(), version1.get(), NULL);
// Disassociating the registration should clear all version attributes. // Disassociating the registration should clear all version attributes.
provider_host2_->UnassociateRegistration(); provider_host2_->DisassociateRegistration();
VerifyVersionAttributes( VerifyVersionAttributes(
provider_host1_, version2.get(), version1.get(), NULL); provider_host1_, version2.get(), version1.get(), NULL);
VerifyVersionAttributes(provider_host2_, NULL, NULL, NULL); VerifyVersionAttributes(provider_host2_, NULL, NULL, NULL);
......
...@@ -54,6 +54,10 @@ ServiceWorkerDispatcher::~ServiceWorkerDispatcher() { ...@@ -54,6 +54,10 @@ ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
bool handled = true; bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg) IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistration,
OnAssociateRegistration)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DisassociateRegistration,
OnDisassociateRegistration)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, OnRegistered) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, OnRegistered)
IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered, IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered,
OnUnregistered) OnUnregistered)
...@@ -219,24 +223,29 @@ WebServiceWorkerImpl* ServiceWorkerDispatcher::GetServiceWorker( ...@@ -219,24 +223,29 @@ WebServiceWorkerImpl* ServiceWorkerDispatcher::GetServiceWorker(
} }
WebServiceWorkerRegistrationImpl* WebServiceWorkerRegistrationImpl*
ServiceWorkerDispatcher::GetServiceWorkerRegistration( ServiceWorkerDispatcher::FindServiceWorkerRegistration(
const ServiceWorkerRegistrationObjectInfo& info, const ServiceWorkerRegistrationObjectInfo& info,
bool adopt_handle) { bool adopt_handle) {
if (info.handle_id == kInvalidServiceWorkerRegistrationHandleId) RegistrationObjectMap::iterator registration =
return NULL;
RegistrationObjectMap::iterator existing_registration =
registrations_.find(info.handle_id); registrations_.find(info.handle_id);
if (registration == registrations_.end())
if (existing_registration != registrations_.end()) { return NULL;
if (adopt_handle) { if (adopt_handle) {
// We are instructed to adopt a handle but we already have one, so // We are instructed to adopt a handle but we already have one, so
// adopt and destroy a handle ref. // adopt and destroy a handle ref.
ServiceWorkerRegistrationHandleReference::Adopt( ServiceWorkerRegistrationHandleReference::Adopt(
info, thread_safe_sender_.get()); info, thread_safe_sender_.get());
} }
return existing_registration->second; return registration->second;
} }
WebServiceWorkerRegistrationImpl*
ServiceWorkerDispatcher::CreateServiceWorkerRegistration(
const ServiceWorkerRegistrationObjectInfo& info,
bool adopt_handle) {
DCHECK(!FindServiceWorkerRegistration(info, adopt_handle));
if (info.handle_id == kInvalidServiceWorkerRegistrationHandleId)
return NULL;
scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref = scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref =
adopt_handle ? ServiceWorkerRegistrationHandleReference::Adopt( adopt_handle ? ServiceWorkerRegistrationHandleReference::Adopt(
...@@ -249,6 +258,36 @@ ServiceWorkerDispatcher::GetServiceWorkerRegistration( ...@@ -249,6 +258,36 @@ ServiceWorkerDispatcher::GetServiceWorkerRegistration(
return new WebServiceWorkerRegistrationImpl(handle_ref.Pass()); return new WebServiceWorkerRegistrationImpl(handle_ref.Pass());
} }
void ServiceWorkerDispatcher::OnAssociateRegistration(
int thread_id,
int provider_id,
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs) {
ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
if (provider == provider_contexts_.end())
return;
provider->second->OnAssociateRegistration(info, attrs);
if (attrs.installing.handle_id != kInvalidServiceWorkerHandleId)
worker_to_provider_[attrs.installing.handle_id] = provider->second;
if (attrs.waiting.handle_id != kInvalidServiceWorkerHandleId)
worker_to_provider_[attrs.waiting.handle_id] = provider->second;
if (attrs.active.handle_id != kInvalidServiceWorkerHandleId)
worker_to_provider_[attrs.active.handle_id] = provider->second;
}
void ServiceWorkerDispatcher::OnDisassociateRegistration(
int thread_id,
int provider_id) {
ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
if (provider == provider_contexts_.end())
return;
provider->second->OnDisassociateRegistration();
worker_to_provider_.erase(provider->second->installing_handle_id());
worker_to_provider_.erase(provider->second->waiting_handle_id());
worker_to_provider_.erase(provider->second->active_handle_id());
worker_to_provider_.erase(provider->second->controller_handle_id());
}
void ServiceWorkerDispatcher::OnRegistered( void ServiceWorkerDispatcher::OnRegistered(
int thread_id, int thread_id,
int request_id, int request_id,
...@@ -265,10 +304,22 @@ void ServiceWorkerDispatcher::OnRegistered( ...@@ -265,10 +304,22 @@ void ServiceWorkerDispatcher::OnRegistered(
return; return;
WebServiceWorkerRegistrationImpl* registration = WebServiceWorkerRegistrationImpl* registration =
GetServiceWorkerRegistration(info, true); FindServiceWorkerRegistration(info, true);
if (!registration) {
registration = CreateServiceWorkerRegistration(info, true);
registration->SetInstalling(GetServiceWorker(attrs.installing, true)); registration->SetInstalling(GetServiceWorker(attrs.installing, true));
registration->SetWaiting(GetServiceWorker(attrs.waiting, true)); registration->SetWaiting(GetServiceWorker(attrs.waiting, true));
registration->SetActive(GetServiceWorker(attrs.active, true)); registration->SetActive(GetServiceWorker(attrs.active, true));
} else {
// |registration| must already have version attributes, so adopt and destroy
// handle refs for them.
ServiceWorkerHandleReference::Adopt(
attrs.installing, thread_safe_sender_.get());
ServiceWorkerHandleReference::Adopt(
attrs.waiting, thread_safe_sender_.get());
ServiceWorkerHandleReference::Adopt(
attrs.active, thread_safe_sender_.get());
}
callbacks->onSuccess(registration); callbacks->onSuccess(registration);
pending_registration_callbacks_.Remove(request_id); pending_registration_callbacks_.Remove(request_id);
...@@ -387,6 +438,7 @@ void ServiceWorkerDispatcher::OnSetVersionAttributes( ...@@ -387,6 +438,7 @@ void ServiceWorkerDispatcher::OnSetVersionAttributes(
SetActiveServiceWorker(provider_id, SetActiveServiceWorker(provider_id,
registration_handle_id, registration_handle_id,
attributes.active); attributes.active);
SetReadyRegistration(provider_id, registration_handle_id);
} }
} }
...@@ -405,7 +457,8 @@ void ServiceWorkerDispatcher::SetInstallingServiceWorker( ...@@ -405,7 +457,8 @@ void ServiceWorkerDispatcher::SetInstallingServiceWorker(
int registration_handle_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
ProviderContextMap::iterator provider = provider_contexts_.find(provider_id); ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
if (provider != provider_contexts_.end()) { if (provider != provider_contexts_.end() &&
provider->second->registration_handle_id() == registration_handle_id) {
int existing_installing_id = provider->second->installing_handle_id(); int existing_installing_id = provider->second->installing_handle_id();
if (existing_installing_id != info.handle_id && if (existing_installing_id != info.handle_id &&
existing_installing_id != kInvalidServiceWorkerHandleId) { existing_installing_id != kInvalidServiceWorkerHandleId) {
...@@ -415,7 +468,8 @@ void ServiceWorkerDispatcher::SetInstallingServiceWorker( ...@@ -415,7 +468,8 @@ void ServiceWorkerDispatcher::SetInstallingServiceWorker(
DCHECK(associated_provider->second->provider_id() == provider_id); DCHECK(associated_provider->second->provider_id() == provider_id);
worker_to_provider_.erase(associated_provider); worker_to_provider_.erase(associated_provider);
} }
provider->second->OnSetInstallingServiceWorker(provider_id, info); provider->second->OnSetInstallingServiceWorker(
registration_handle_id, info);
if (info.handle_id != kInvalidServiceWorkerHandleId) if (info.handle_id != kInvalidServiceWorkerHandleId)
worker_to_provider_[info.handle_id] = provider->second; worker_to_provider_[info.handle_id] = provider->second;
} }
...@@ -433,7 +487,8 @@ void ServiceWorkerDispatcher::SetWaitingServiceWorker( ...@@ -433,7 +487,8 @@ void ServiceWorkerDispatcher::SetWaitingServiceWorker(
int registration_handle_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
ProviderContextMap::iterator provider = provider_contexts_.find(provider_id); ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
if (provider != provider_contexts_.end()) { if (provider != provider_contexts_.end() &&
provider->second->registration_handle_id() == registration_handle_id) {
int existing_waiting_id = provider->second->waiting_handle_id(); int existing_waiting_id = provider->second->waiting_handle_id();
if (existing_waiting_id != info.handle_id && if (existing_waiting_id != info.handle_id &&
existing_waiting_id != kInvalidServiceWorkerHandleId) { existing_waiting_id != kInvalidServiceWorkerHandleId) {
...@@ -443,7 +498,7 @@ void ServiceWorkerDispatcher::SetWaitingServiceWorker( ...@@ -443,7 +498,7 @@ void ServiceWorkerDispatcher::SetWaitingServiceWorker(
DCHECK(associated_provider->second->provider_id() == provider_id); DCHECK(associated_provider->second->provider_id() == provider_id);
worker_to_provider_.erase(associated_provider); worker_to_provider_.erase(associated_provider);
} }
provider->second->OnSetWaitingServiceWorker(provider_id, info); provider->second->OnSetWaitingServiceWorker(registration_handle_id, info);
if (info.handle_id != kInvalidServiceWorkerHandleId) if (info.handle_id != kInvalidServiceWorkerHandleId)
worker_to_provider_[info.handle_id] = provider->second; worker_to_provider_[info.handle_id] = provider->second;
} }
...@@ -461,7 +516,8 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker( ...@@ -461,7 +516,8 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker(
int registration_handle_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
ProviderContextMap::iterator provider = provider_contexts_.find(provider_id); ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
if (provider != provider_contexts_.end()) { if (provider != provider_contexts_.end() &&
provider->second->registration_handle_id() == registration_handle_id) {
int existing_active_id = provider->second->active_handle_id(); int existing_active_id = provider->second->active_handle_id();
if (existing_active_id != info.handle_id && if (existing_active_id != info.handle_id &&
existing_active_id != kInvalidServiceWorkerHandleId) { existing_active_id != kInvalidServiceWorkerHandleId) {
...@@ -471,7 +527,7 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker( ...@@ -471,7 +527,7 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker(
DCHECK(associated_provider->second->provider_id() == provider_id); DCHECK(associated_provider->second->provider_id() == provider_id);
worker_to_provider_.erase(associated_provider); worker_to_provider_.erase(associated_provider);
} }
provider->second->OnSetActiveServiceWorker(provider_id, info); provider->second->OnSetActiveServiceWorker(registration_handle_id, info);
if (info.handle_id != kInvalidServiceWorkerHandleId) if (info.handle_id != kInvalidServiceWorkerHandleId)
worker_to_provider_[info.handle_id] = provider->second; worker_to_provider_[info.handle_id] = provider->second;
} }
...@@ -484,6 +540,37 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker( ...@@ -484,6 +540,37 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker(
} }
} }
void ServiceWorkerDispatcher::SetReadyRegistration(
int provider_id,
int registration_handle_id) {
ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
if (provider == provider_contexts_.end() ||
provider->second->registration_handle_id() != registration_handle_id ||
provider->second->active_handle_id() == kInvalidServiceWorkerHandleId) {
return;
}
ScriptClientMap::iterator client = script_clients_.find(provider_id);
if (client == script_clients_.end())
return;
ServiceWorkerRegistrationObjectInfo info =
provider->second->registration()->info();
WebServiceWorkerRegistrationImpl* registration =
FindServiceWorkerRegistration(info, false);
if (!registration) {
registration = CreateServiceWorkerRegistration(info, false);
ServiceWorkerVersionAttributes attrs =
provider->second->GetVersionAttributes();
registration->SetInstalling(GetServiceWorker(attrs.installing, false));
registration->SetWaiting(GetServiceWorker(attrs.waiting, false));
registration->SetActive(GetServiceWorker(attrs.active, false));
}
// Resolve the .ready promise with the registration object.
client->second->setReadyRegistration(registration);
}
void ServiceWorkerDispatcher::OnSetControllerServiceWorker( void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
int thread_id, int thread_id,
int provider_id, int provider_id,
...@@ -494,7 +581,8 @@ void ServiceWorkerDispatcher::OnSetControllerServiceWorker( ...@@ -494,7 +581,8 @@ void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
"Provider ID", provider_id); "Provider ID", provider_id);
ProviderContextMap::iterator provider = provider_contexts_.find(provider_id); ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
if (provider != provider_contexts_.end()) { if (provider != provider_contexts_.end()) {
provider->second->OnSetControllerServiceWorker(provider_id, info); provider->second->OnSetControllerServiceWorker(
provider->second->registration_handle_id(), info);
worker_to_provider_[info.handle_id] = provider->second; worker_to_provider_[info.handle_id] = provider->second;
} }
......
...@@ -96,12 +96,19 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -96,12 +96,19 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
const ServiceWorkerObjectInfo& info, const ServiceWorkerObjectInfo& info,
bool adopt_handle); bool adopt_handle);
// If an existing WebServiceWorkerRegistrationImpl exists for the // Finds a WebServiceWorkerRegistrationImpl for the specified registration.
// registration, it is returned; otherwise a WebServiceWorkerRegistrationImpl // If it's not found, returns NULL. If |adopt_handle| is true,
// is created and its ownership is transferred to the caller. If // a ServiceWorkerRegistrationHandleReference will be adopted for the
// |adopt_handle| is true, a ServiceWorkerRegistrationHandleReference will be // registration.
// adopted for the specified registration. WebServiceWorkerRegistrationImpl* FindServiceWorkerRegistration(
WebServiceWorkerRegistrationImpl* GetServiceWorkerRegistration( const ServiceWorkerRegistrationObjectInfo& info,
bool adopt_handle);
// Creates a WebServiceWorkerRegistrationImpl for the specified registration
// and transfers its ownership to the caller. If |adopt_handle| is true, a
// ServiceWorkerRegistrationHandleReference will be adopted for the
// registration.
WebServiceWorkerRegistrationImpl* CreateServiceWorkerRegistration(
const ServiceWorkerRegistrationObjectInfo& info, const ServiceWorkerRegistrationObjectInfo& info,
bool adopt_handle); bool adopt_handle);
...@@ -132,6 +139,12 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -132,6 +139,12 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
// WorkerTaskRunner::Observer implementation. // WorkerTaskRunner::Observer implementation.
virtual void OnWorkerRunLoopStopped() OVERRIDE; virtual void OnWorkerRunLoopStopped() OVERRIDE;
void OnAssociateRegistration(int thread_id,
int provider_id,
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
void OnDisassociateRegistration(int thread_id,
int provider_id);
void OnRegistered(int thread_id, void OnRegistered(int thread_id,
int request_id, int request_id,
const ServiceWorkerRegistrationObjectInfo& info, const ServiceWorkerRegistrationObjectInfo& info,
...@@ -178,6 +191,9 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -178,6 +191,9 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
int provider_id, int provider_id,
int registration_handle_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void SetReadyRegistration(
int provider_id,
int registration_handle_id);
// Keeps map from handle_id to ServiceWorker object. // Keeps map from handle_id to ServiceWorker object.
void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker); void AddServiceWorker(int handle_id, WebServiceWorkerImpl* worker);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "content/child/child_thread.h" #include "content/child/child_thread.h"
#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_handle_reference.h" #include "content/child/service_worker/service_worker_handle_reference.h"
#include "content/child/service_worker/service_worker_registration_handle_reference.h"
#include "content/child/thread_safe_sender.h" #include "content/child/thread_safe_sender.h"
#include "content/child/worker_task_runner.h" #include "content/child/worker_task_runner.h"
#include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_messages.h"
...@@ -56,6 +57,47 @@ ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() { ...@@ -56,6 +57,47 @@ ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() {
return controller_.get(); return controller_.get();
} }
ServiceWorkerRegistrationHandleReference*
ServiceWorkerProviderContext::registration() {
DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
return registration_.get();
}
ServiceWorkerVersionAttributes
ServiceWorkerProviderContext::GetVersionAttributes() {
ServiceWorkerVersionAttributes attrs;
if (installing())
attrs.installing = installing()->info();
if (waiting())
attrs.waiting = waiting()->info();
if (active())
attrs.active = active()->info();
return attrs;
}
void ServiceWorkerProviderContext::OnAssociateRegistration(
const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs) {
DCHECK(!registration_);
DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId, info.handle_id);
registration_ = ServiceWorkerRegistrationHandleReference::Adopt(
info, thread_safe_sender_.get());
installing_ = ServiceWorkerHandleReference::Adopt(
attrs.installing, thread_safe_sender_.get());
waiting_ = ServiceWorkerHandleReference::Adopt(
attrs.waiting, thread_safe_sender_.get());
active_ = ServiceWorkerHandleReference::Adopt(
attrs.active, thread_safe_sender_.get());
}
void ServiceWorkerProviderContext::OnDisassociateRegistration() {
controller_.reset();
active_.reset();
waiting_.reset();
installing_.reset();
registration_.reset();
}
void ServiceWorkerProviderContext::OnServiceWorkerStateChanged( void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
int handle_id, int handle_id,
blink::WebServiceWorkerState state) { blink::WebServiceWorkerState state) {
...@@ -80,33 +122,33 @@ void ServiceWorkerProviderContext::OnServiceWorkerStateChanged( ...@@ -80,33 +122,33 @@ void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
} }
void ServiceWorkerProviderContext::OnSetInstallingServiceWorker( void ServiceWorkerProviderContext::OnSetInstallingServiceWorker(
int provider_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
DCHECK_EQ(provider_id_, provider_id); DCHECK(IsAssociatedWithRegistration(registration_handle_id));
installing_ = installing_ =
ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get()); ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
} }
void ServiceWorkerProviderContext::OnSetWaitingServiceWorker( void ServiceWorkerProviderContext::OnSetWaitingServiceWorker(
int provider_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
DCHECK_EQ(provider_id_, provider_id); DCHECK(IsAssociatedWithRegistration(registration_handle_id));
waiting_ = waiting_ =
ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get()); ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
} }
void ServiceWorkerProviderContext::OnSetActiveServiceWorker( void ServiceWorkerProviderContext::OnSetActiveServiceWorker(
int provider_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
DCHECK_EQ(provider_id_, provider_id); DCHECK(IsAssociatedWithRegistration(registration_handle_id));
active_ = active_ =
ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get()); ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get());
} }
void ServiceWorkerProviderContext::OnSetControllerServiceWorker( void ServiceWorkerProviderContext::OnSetControllerServiceWorker(
int provider_id, int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
DCHECK_EQ(provider_id_, provider_id); DCHECK(IsAssociatedWithRegistration(registration_handle_id));
// This context is is the primary owner of this handle, keeps the // This context is is the primary owner of this handle, keeps the
// initial reference until it goes away. // initial reference until it goes away.
...@@ -141,4 +183,19 @@ int ServiceWorkerProviderContext::controller_handle_id() const { ...@@ -141,4 +183,19 @@ int ServiceWorkerProviderContext::controller_handle_id() const {
: kInvalidServiceWorkerHandleId; : kInvalidServiceWorkerHandleId;
} }
int ServiceWorkerProviderContext::registration_handle_id() const {
DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
return registration_ ? registration_->info().handle_id
: kInvalidServiceWorkerRegistrationHandleId;
}
bool ServiceWorkerProviderContext::IsAssociatedWithRegistration(
int registration_handle_id) const {
if (!registration_)
return false;
if (registration_handle_id == kInvalidServiceWorkerRegistrationHandleId)
return false;
return registration_->info().handle_id == registration_handle_id;
}
} // namespace content } // namespace content
...@@ -24,6 +24,7 @@ class Message; ...@@ -24,6 +24,7 @@ class Message;
namespace content { namespace content {
class ServiceWorkerHandleReference; class ServiceWorkerHandleReference;
class ServiceWorkerRegistrationHandleReference;
struct ServiceWorkerProviderContextDeleter; struct ServiceWorkerProviderContextDeleter;
class ThreadSafeSender; class ThreadSafeSender;
...@@ -38,15 +39,18 @@ class ServiceWorkerProviderContext ...@@ -38,15 +39,18 @@ class ServiceWorkerProviderContext
explicit ServiceWorkerProviderContext(int provider_id); explicit ServiceWorkerProviderContext(int provider_id);
// Called from ServiceWorkerDispatcher. // Called from ServiceWorkerDispatcher.
void OnAssociateRegistration(const ServiceWorkerRegistrationObjectInfo& info,
const ServiceWorkerVersionAttributes& attrs);
void OnDisassociateRegistration();
void OnServiceWorkerStateChanged(int handle_id, void OnServiceWorkerStateChanged(int handle_id,
blink::WebServiceWorkerState state); blink::WebServiceWorkerState state);
void OnSetInstallingServiceWorker(int provider_id, void OnSetInstallingServiceWorker(int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void OnSetWaitingServiceWorker(int provider_id, void OnSetWaitingServiceWorker(int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void OnSetActiveServiceWorker(int provider_id, void OnSetActiveServiceWorker(int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void OnSetControllerServiceWorker(int provider_id, void OnSetControllerServiceWorker(int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
int provider_id() const { return provider_id_; } int provider_id() const { return provider_id_; }
...@@ -55,6 +59,9 @@ class ServiceWorkerProviderContext ...@@ -55,6 +59,9 @@ class ServiceWorkerProviderContext
ServiceWorkerHandleReference* waiting(); ServiceWorkerHandleReference* waiting();
ServiceWorkerHandleReference* active(); ServiceWorkerHandleReference* active();
ServiceWorkerHandleReference* controller(); ServiceWorkerHandleReference* controller();
ServiceWorkerRegistrationHandleReference* registration();
ServiceWorkerVersionAttributes GetVersionAttributes();
// Gets the handle ID of the installing Service Worker, or // Gets the handle ID of the installing Service Worker, or
// kInvalidServiceWorkerHandleId if the provider does not have a // kInvalidServiceWorkerHandleId if the provider does not have a
...@@ -76,10 +83,17 @@ class ServiceWorkerProviderContext ...@@ -76,10 +83,17 @@ class ServiceWorkerProviderContext
// by a Service Worker. // by a Service Worker.
int controller_handle_id() const; int controller_handle_id() const;
// Gets the handle ID of the associated registration, or
// kInvalidRegistrationHandleId if the provider is not associated with any
// registration.
int registration_handle_id() const;
private: private:
friend class base::RefCounted<ServiceWorkerProviderContext>; friend class base::RefCounted<ServiceWorkerProviderContext>;
~ServiceWorkerProviderContext(); ~ServiceWorkerProviderContext();
bool IsAssociatedWithRegistration(int registration_handle_id) const;
const int provider_id_; const int provider_id_;
scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_; scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_;
scoped_refptr<ThreadSafeSender> thread_safe_sender_; scoped_refptr<ThreadSafeSender> thread_safe_sender_;
...@@ -87,6 +101,7 @@ class ServiceWorkerProviderContext ...@@ -87,6 +101,7 @@ class ServiceWorkerProviderContext
scoped_ptr<ServiceWorkerHandleReference> waiting_; scoped_ptr<ServiceWorkerHandleReference> waiting_;
scoped_ptr<ServiceWorkerHandleReference> active_; scoped_ptr<ServiceWorkerHandleReference> active_;
scoped_ptr<ServiceWorkerHandleReference> controller_; scoped_ptr<ServiceWorkerHandleReference> controller_;
scoped_ptr<ServiceWorkerRegistrationHandleReference> registration_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContext); DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContext);
}; };
......
...@@ -30,6 +30,7 @@ class ServiceWorkerRegistrationHandleReference { ...@@ -30,6 +30,7 @@ class ServiceWorkerRegistrationHandleReference {
~ServiceWorkerRegistrationHandleReference(); ~ServiceWorkerRegistrationHandleReference();
const ServiceWorkerRegistrationObjectInfo& info() const { return info_; }
int handle_id() const { return info_.handle_id; } int handle_id() const { return info_.handle_id; }
GURL scope() const { return info_.scope; } GURL scope() const { return info_.scope; }
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#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_handle_reference.h" #include "content/child/service_worker/service_worker_handle_reference.h"
#include "content/child/service_worker/service_worker_provider_context.h" #include "content/child/service_worker/service_worker_provider_context.h"
#include "content/child/service_worker/service_worker_registration_handle_reference.h"
#include "content/child/service_worker/web_service_worker_impl.h" #include "content/child/service_worker/web_service_worker_impl.h"
#include "content/child/service_worker/web_service_worker_registration_impl.h"
#include "content/child/thread_safe_sender.h" #include "content/child/thread_safe_sender.h"
#include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_messages.h"
#include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h" #include "third_party/WebKit/public/platform/WebServiceWorkerProviderClient.h"
...@@ -47,6 +49,30 @@ void WebServiceWorkerProviderImpl::setClient( ...@@ -47,6 +49,30 @@ void WebServiceWorkerProviderImpl::setClient(
// for more context) // for more context)
GetDispatcher()->AddScriptClient(provider_id_, client); GetDispatcher()->AddScriptClient(provider_id_, client);
if (!context_->registration()) {
// This provider is not associated with any registration.
return;
}
// Set .ready if the associated registration has the active service worker.
if (context_->active_handle_id() != kInvalidServiceWorkerHandleId) {
WebServiceWorkerRegistrationImpl* registration =
GetDispatcher()->FindServiceWorkerRegistration(
context_->registration()->info(), false);
if (!registration) {
registration = GetDispatcher()->CreateServiceWorkerRegistration(
context_->registration()->info(), false);
ServiceWorkerVersionAttributes attrs = context_->GetVersionAttributes();
registration->SetInstalling(
GetDispatcher()->GetServiceWorker(attrs.installing, false));
registration->SetWaiting(
GetDispatcher()->GetServiceWorker(attrs.waiting, false));
registration->SetActive(
GetDispatcher()->GetServiceWorker(attrs.active, false));
}
client->setReadyRegistration(registration);
}
if (context_->controller_handle_id() != kInvalidServiceWorkerHandleId) { if (context_->controller_handle_id() != kInvalidServiceWorkerHandleId) {
client->setController(GetDispatcher()->GetServiceWorker( client->setController(GetDispatcher()->GetServiceWorker(
context_->controller()->info(), false)); context_->controller()->info(), false));
......
...@@ -184,6 +184,17 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_CacheStorageKeys, ...@@ -184,6 +184,17 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_CacheStorageKeys,
// extract it and dispatch the message to the correct ServiceWorkerDispatcher // extract it and dispatch the message to the correct ServiceWorkerDispatcher
// on the correct thread. // on the correct thread.
// Informs the child process that the given provider gets associated or
// disassociated with the registration.
IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_AssociateRegistration,
int /* thread_id */,
int /* provider_id */,
content::ServiceWorkerRegistrationObjectInfo,
content::ServiceWorkerVersionAttributes)
IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_DisassociateRegistration,
int /* thread_id */,
int /* provider_id */)
// Response to ServiceWorkerMsg_RegisterServiceWorker. // Response to ServiceWorkerMsg_RegisterServiceWorker.
IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_ServiceWorkerRegistered, IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_ServiceWorkerRegistered,
int /* thread_id */, int /* thread_id */,
......
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