Commit 61752d1c authored by nhiroki@chromium.org's avatar nhiroki@chromium.org

ServiceWorker: Implement updatefound event and version attributes (Chromium)

Changes in the renderer side:
* Implementing WebServiceWorkerRegistrationImpl in order to handle 'updatefound'
event and version attributes.
* Adding ServiceWorkerRegistrationHandleReference which is responsible for
incrementing/decrementing the refcount of ServiceWorkerRegistration in the
browser-side (in the same way as ServiceWorkerHandleRefernce).

Changes in the browser side:
* Adding ServiceWorkerRegistrationHandle which manages the refcount of
ServiceWorkerRegistration and listens to its version change events.
This is managed by ServiceWorkerDispatcherHost.

Changes in the wiring part:
* Adding new IPC messages for refcount operations.
* Changing Registered and SetVersionAttributes messages to carry the
registration handle id.


BUG=384119, 396400
TEST=content_unittests --gtest_filter=ServiceWorker*
TEST=run_webkit_tests.py --debug http/tests/serviceworker
TEST=https://codereview.chromium.org/466723002/ (layout tests for ServiceWorkerRegistration)
NOTRY=true

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

Cr-Commit-Position: refs/heads/master@{#289415}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289415 0039d316-1c4b-4281-b951-d872f2087c98
parent cf1a3fbd
...@@ -102,6 +102,7 @@ ServiceWorkerContextCore::ServiceWorkerContextCore( ...@@ -102,6 +102,7 @@ ServiceWorkerContextCore::ServiceWorkerContextCore(
embedded_worker_registry_(EmbeddedWorkerRegistry::Create(AsWeakPtr())), embedded_worker_registry_(EmbeddedWorkerRegistry::Create(AsWeakPtr())),
job_coordinator_(new ServiceWorkerJobCoordinator(AsWeakPtr())), job_coordinator_(new ServiceWorkerJobCoordinator(AsWeakPtr())),
next_handle_id_(0), next_handle_id_(0),
next_registration_handle_id_(0),
observer_list_(observer_list) { observer_list_(observer_list) {
} }
...@@ -120,6 +121,7 @@ ServiceWorkerContextCore::ServiceWorkerContextCore( ...@@ -120,6 +121,7 @@ ServiceWorkerContextCore::ServiceWorkerContextCore(
old_context->embedded_worker_registry())), old_context->embedded_worker_registry())),
job_coordinator_(new ServiceWorkerJobCoordinator(AsWeakPtr())), job_coordinator_(new ServiceWorkerJobCoordinator(AsWeakPtr())),
next_handle_id_(0), next_handle_id_(0),
next_registration_handle_id_(0),
observer_list_(old_context->observer_list_) { observer_list_(old_context->observer_list_) {
} }
...@@ -317,6 +319,10 @@ int ServiceWorkerContextCore::GetNewServiceWorkerHandleId() { ...@@ -317,6 +319,10 @@ int ServiceWorkerContextCore::GetNewServiceWorkerHandleId() {
return next_handle_id_++; return next_handle_id_++;
} }
int ServiceWorkerContextCore::GetNewRegistrationHandleId() {
return next_registration_handle_id_++;
}
void ServiceWorkerContextCore::ScheduleDeleteAndStartOver() const { void ServiceWorkerContextCore::ScheduleDeleteAndStartOver() const {
storage_->Disable(); storage_->Disable();
base::MessageLoop::current()->PostTask( base::MessageLoop::current()->PostTask(
......
...@@ -168,8 +168,9 @@ class CONTENT_EXPORT ServiceWorkerContextCore ...@@ -168,8 +168,9 @@ class CONTENT_EXPORT ServiceWorkerContextCore
std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo(); std::vector<ServiceWorkerRegistrationInfo> GetAllLiveRegistrationInfo();
std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo(); std::vector<ServiceWorkerVersionInfo> GetAllLiveVersionInfo();
// Returns new context-local unique ID for ServiceWorkerHandle. // Returns new context-local unique ID.
int GetNewServiceWorkerHandleId(); int GetNewServiceWorkerHandleId();
int GetNewRegistrationHandleId();
void ScheduleDeleteAndStartOver() const; void ScheduleDeleteAndStartOver() const;
...@@ -216,6 +217,7 @@ class CONTENT_EXPORT ServiceWorkerContextCore ...@@ -216,6 +217,7 @@ class CONTENT_EXPORT ServiceWorkerContextCore
std::map<int64, ServiceWorkerRegistration*> live_registrations_; std::map<int64, ServiceWorkerRegistration*> live_registrations_;
std::map<int64, ServiceWorkerVersion*> live_versions_; std::map<int64, ServiceWorkerVersion*> live_versions_;
int next_handle_id_; int next_handle_id_;
int next_registration_handle_id_;
scoped_refptr<ObserverListThreadSafe<ServiceWorkerContextObserver> > scoped_refptr<ObserverListThreadSafe<ServiceWorkerContextObserver> >
observer_list_; observer_list_;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_handle.h" #include "content/browser/service_worker/service_worker_handle.h"
#include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_registration_handle.h"
#include "content/browser/service_worker/service_worker_utils.h" #include "content/browser/service_worker/service_worker_utils.h"
#include "content/common/service_worker/embedded_worker_messages.h" #include "content/common/service_worker/embedded_worker_messages.h"
#include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_messages.h"
...@@ -135,6 +136,10 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived( ...@@ -135,6 +136,10 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(
OnIncrementServiceWorkerRefCount) OnIncrementServiceWorkerRefCount)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount, IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
OnDecrementServiceWorkerRefCount) OnDecrementServiceWorkerRefCount)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementRegistrationRefCount,
OnIncrementRegistrationRefCount)
IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementRegistrationRefCount,
OnDecrementRegistrationRefCount)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
...@@ -165,6 +170,12 @@ void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle( ...@@ -165,6 +170,12 @@ void ServiceWorkerDispatcherHost::RegisterServiceWorkerHandle(
handles_.AddWithID(handle.release(), handle_id); handles_.AddWithID(handle.release(), handle_id);
} }
void ServiceWorkerDispatcherHost::RegisterServiceWorkerRegistrationHandle(
scoped_ptr<ServiceWorkerRegistrationHandle> handle) {
int handle_id = handle->handle_id();
registration_handles_.AddWithID(handle.release(), handle_id);
}
void ServiceWorkerDispatcherHost::OnRegisterServiceWorker( void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(
int thread_id, int thread_id,
int request_id, int request_id,
...@@ -331,6 +342,23 @@ ServiceWorkerHandle* ServiceWorkerDispatcherHost::FindHandle(int provider_id, ...@@ -331,6 +342,23 @@ ServiceWorkerHandle* ServiceWorkerDispatcherHost::FindHandle(int provider_id,
return NULL; return NULL;
} }
ServiceWorkerRegistrationHandle*
ServiceWorkerDispatcherHost::FindRegistrationHandle(int provider_id,
int64 registration_id) {
for (IDMap<ServiceWorkerRegistrationHandle, IDMapOwnPointer>::iterator
iter(&registration_handles_);
!iter.IsAtEnd();
iter.Advance()) {
ServiceWorkerRegistrationHandle* handle = iter.GetCurrentValue();
DCHECK(handle);
if (handle->provider_id() == provider_id && handle->registration() &&
handle->registration()->id() == registration_id) {
return handle;
}
}
return NULL;
}
void ServiceWorkerDispatcherHost::RegistrationComplete( void ServiceWorkerDispatcherHost::RegistrationComplete(
int thread_id, int thread_id,
int provider_id, int provider_id,
...@@ -350,6 +378,7 @@ void ServiceWorkerDispatcherHost::RegistrationComplete( ...@@ -350,6 +378,7 @@ void ServiceWorkerDispatcherHost::RegistrationComplete(
DCHECK(version); DCHECK(version);
DCHECK_EQ(registration_id, version->registration_id()); DCHECK_EQ(registration_id, version->registration_id());
ServiceWorkerObjectInfo info; ServiceWorkerObjectInfo info;
ServiceWorkerHandle* handle = FindHandle(provider_id, version_id); ServiceWorkerHandle* handle = FindHandle(provider_id, version_id);
if (handle) { if (handle) {
DCHECK_EQ(thread_id, handle->thread_id()); DCHECK_EQ(thread_id, handle->thread_id());
...@@ -361,8 +390,27 @@ void ServiceWorkerDispatcherHost::RegistrationComplete( ...@@ -361,8 +390,27 @@ void ServiceWorkerDispatcherHost::RegistrationComplete(
info = new_handle->GetObjectInfo(); info = new_handle->GetObjectInfo();
RegisterServiceWorkerHandle(new_handle.Pass()); RegisterServiceWorkerHandle(new_handle.Pass());
} }
ServiceWorkerRegistration* registration =
GetContext()->GetLiveRegistration(registration_id);
DCHECK(registration);
ServiceWorkerRegistrationHandle* registration_handle =
FindRegistrationHandle(provider_id, registration_id);
int registration_handle_id = kInvalidServiceWorkerRegistrationHandleId;
if (registration_handle) {
registration_handle->IncrementRefCount();
registration_handle_id = registration_handle->handle_id();
} else {
scoped_ptr<ServiceWorkerRegistrationHandle> new_handle(
new ServiceWorkerRegistrationHandle(
GetContext()->AsWeakPtr(), this, provider_id, registration));
registration_handle_id = new_handle->handle_id();
RegisterServiceWorkerRegistrationHandle(new_handle.Pass());
}
Send(new ServiceWorkerMsg_ServiceWorkerRegistered( Send(new ServiceWorkerMsg_ServiceWorkerRegistered(
thread_id, request_id, info)); thread_id, request_id, registration_handle_id, info));
} }
void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(int embedded_worker_id) { void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(int embedded_worker_id) {
...@@ -467,6 +515,30 @@ void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount( ...@@ -467,6 +515,30 @@ void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(
handles_.Remove(handle_id); handles_.Remove(handle_id);
} }
void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(
int registration_handle_id) {
ServiceWorkerRegistrationHandle* handle =
registration_handles_.Lookup(registration_handle_id);
if (!handle) {
BadMessageReceived();
return;
}
handle->IncrementRefCount();
}
void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(
int registration_handle_id) {
ServiceWorkerRegistrationHandle* handle =
registration_handles_.Lookup(registration_handle_id);
if (!handle) {
BadMessageReceived();
return;
}
handle->DecrementRefCount();
if (handle->HasNoRefCount())
registration_handles_.Remove(registration_handle_id);
}
void ServiceWorkerDispatcherHost::UnregistrationComplete( void ServiceWorkerDispatcherHost::UnregistrationComplete(
int thread_id, int thread_id,
int request_id, int request_id,
......
...@@ -24,6 +24,7 @@ class ServiceWorkerContextWrapper; ...@@ -24,6 +24,7 @@ class ServiceWorkerContextWrapper;
class ServiceWorkerHandle; class ServiceWorkerHandle;
class ServiceWorkerProviderHost; class ServiceWorkerProviderHost;
class ServiceWorkerRegistration; class ServiceWorkerRegistration;
class ServiceWorkerRegistrationHandle;
class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter { class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
public: public:
...@@ -47,6 +48,8 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter { ...@@ -47,6 +48,8 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
virtual bool Send(IPC::Message* message) OVERRIDE; virtual bool Send(IPC::Message* message) OVERRIDE;
void RegisterServiceWorkerHandle(scoped_ptr<ServiceWorkerHandle> handle); void RegisterServiceWorkerHandle(scoped_ptr<ServiceWorkerHandle> handle);
void RegisterServiceWorkerRegistrationHandle(
scoped_ptr<ServiceWorkerRegistrationHandle> handle);
MessagePortMessageFilter* message_port_message_filter() { MessagePortMessageFilter* message_port_message_filter() {
return message_port_message_filter_; return message_port_message_filter_;
...@@ -92,12 +95,19 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter { ...@@ -92,12 +95,19 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
const std::vector<int>& sent_message_port_ids); const std::vector<int>& sent_message_port_ids);
void OnIncrementServiceWorkerRefCount(int handle_id); void OnIncrementServiceWorkerRefCount(int handle_id);
void OnDecrementServiceWorkerRefCount(int handle_id); void OnDecrementServiceWorkerRefCount(int handle_id);
void OnIncrementRegistrationRefCount(int registration_handle_id);
void OnDecrementRegistrationRefCount(int registration_handle_id);
void OnPostMessageToWorker(int handle_id, void OnPostMessageToWorker(int handle_id,
const base::string16& message, const base::string16& message,
const std::vector<int>& sent_message_port_ids); const std::vector<int>& sent_message_port_ids);
void OnServiceWorkerObjectDestroyed(int handle_id); void OnServiceWorkerObjectDestroyed(int handle_id);
ServiceWorkerHandle* FindHandle(int provider_id, int64 version_id); ServiceWorkerHandle* FindHandle(
int provider_id,
int64 version_id);
ServiceWorkerRegistrationHandle* FindRegistrationHandle(
int provider_id,
int64 registration_id);
// Callbacks from ServiceWorkerContextCore // Callbacks from ServiceWorkerContextCore
void RegistrationComplete(int thread_id, void RegistrationComplete(int thread_id,
...@@ -122,6 +132,7 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter { ...@@ -122,6 +132,7 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter {
scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_; scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_;
IDMap<ServiceWorkerHandle, IDMapOwnPointer> handles_; IDMap<ServiceWorkerHandle, IDMapOwnPointer> handles_;
IDMap<ServiceWorkerRegistrationHandle, IDMapOwnPointer> registration_handles_;
bool channel_ready_; // True after BrowserMessageFilter::sender_ != NULL. bool channel_ready_; // True after BrowserMessageFilter::sender_ != NULL.
ScopedVector<IPC::Message> pending_messages_; ScopedVector<IPC::Message> pending_messages_;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "content/browser/service_worker/service_worker_controllee_request_handler.h" #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
#include "content/browser/service_worker/service_worker_dispatcher_host.h" #include "content/browser/service_worker/service_worker_dispatcher_host.h"
#include "content/browser/service_worker/service_worker_handle.h" #include "content/browser/service_worker/service_worker_handle.h"
#include "content/browser/service_worker/service_worker_registration_handle.h"
#include "content/browser/service_worker/service_worker_utils.h" #include "content/browser/service_worker/service_worker_utils.h"
#include "content/browser/service_worker/service_worker_version.h" #include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_messages.h"
...@@ -99,7 +100,11 @@ void ServiceWorkerProviderHost::SetVersionAttributes( ...@@ -99,7 +100,11 @@ void ServiceWorkerProviderHost::SetVersionAttributes(
attributes.active = CreateHandleAndPass(active_version); attributes.active = CreateHandleAndPass(active_version);
dispatcher_host_->Send(new ServiceWorkerMsg_SetVersionAttributes( dispatcher_host_->Send(new ServiceWorkerMsg_SetVersionAttributes(
kDocumentMainThreadId, provider_id(), mask.changed(), attributes)); kDocumentMainThreadId,
provider_id(),
kInvalidServiceWorkerRegistrationHandleId,
mask.changed(),
attributes));
} }
void ServiceWorkerProviderHost::SetVersionAttributesInternal( void ServiceWorkerProviderHost::SetVersionAttributesInternal(
......
// 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/service_worker/service_worker_registration_handle.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_dispatcher_host.h"
#include "content/browser/service_worker/service_worker_handle.h"
#include "content/common/service_worker/service_worker_messages.h"
namespace content {
static const int kDocumentMainThreadId = 0;
ServiceWorkerRegistrationHandle::ServiceWorkerRegistrationHandle(
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerDispatcherHost* dispatcher_host,
int provider_id,
ServiceWorkerRegistration* registration)
: context_(context),
dispatcher_host_(dispatcher_host),
provider_id_(provider_id),
handle_id_(context ? context->GetNewRegistrationHandleId()
: kInvalidServiceWorkerRegistrationHandleId),
ref_count_(1),
registration_(registration) {
DCHECK(registration_);
SetVersionAttributes(registration->installing_version(),
registration->waiting_version(),
registration->active_version());
registration_->AddListener(this);
}
ServiceWorkerRegistrationHandle::~ServiceWorkerRegistrationHandle() {
registration_->RemoveListener(this);
}
void ServiceWorkerRegistrationHandle::IncrementRefCount() {
DCHECK_GT(ref_count_, 0);
++ref_count_;
}
void ServiceWorkerRegistrationHandle::DecrementRefCount() {
DCHECK_GT(ref_count_, 0);
--ref_count_;
}
void ServiceWorkerRegistrationHandle::OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
ChangedVersionAttributesMask changed_mask,
const ServiceWorkerRegistrationInfo& info) {
DCHECK_EQ(registration->id(), registration_->id());
SetVersionAttributes(registration->installing_version(),
registration->waiting_version(),
registration->active_version());
}
void ServiceWorkerRegistrationHandle::OnRegistrationFailed(
ServiceWorkerRegistration* registration) {
DCHECK_EQ(registration->id(), registration_->id());
ClearVersionAttributes();
registration_->RemoveListener(this);
registration_ = NULL;
}
void ServiceWorkerRegistrationHandle::SetVersionAttributes(
ServiceWorkerVersion* installing_version,
ServiceWorkerVersion* waiting_version,
ServiceWorkerVersion* active_version) {
ChangedVersionAttributesMask mask;
if (installing_version != installing_version_) {
installing_version_ = installing_version;
mask.add(ChangedVersionAttributesMask::INSTALLING_VERSION);
}
if (waiting_version != waiting_version_) {
waiting_version_ = waiting_version;
mask.add(ChangedVersionAttributesMask::WAITING_VERSION);
}
if (active_version != active_version_) {
active_version_ = active_version;
mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION);
}
if (!dispatcher_host_)
return; // Could be NULL in some tests.
if (!mask.changed())
return;
ServiceWorkerVersionAttributes attributes;
if (mask.installing_changed()) {
attributes.installing =
CreateServiceWorkerHandleAndPass(installing_version);
}
if (mask.waiting_changed()) {
attributes.waiting =
CreateServiceWorkerHandleAndPass(waiting_version);
}
if (mask.active_changed()) {
attributes.active =
CreateServiceWorkerHandleAndPass(active_version);
}
dispatcher_host_->Send(new ServiceWorkerMsg_SetVersionAttributes(
kDocumentMainThreadId, provider_id_, handle_id_,
mask.changed(), attributes));
}
void ServiceWorkerRegistrationHandle::ClearVersionAttributes() {
SetVersionAttributes(NULL, NULL, NULL);
}
ServiceWorkerObjectInfo
ServiceWorkerRegistrationHandle::CreateServiceWorkerHandleAndPass(
ServiceWorkerVersion* version) {
ServiceWorkerObjectInfo info;
if (context_ && version) {
scoped_ptr<ServiceWorkerHandle> handle =
ServiceWorkerHandle::Create(context_,
dispatcher_host_,
kDocumentMainThreadId,
provider_id_,
version);
info = handle->GetObjectInfo();
dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
}
return info;
}
} // 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_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_types.h"
namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerDispatcherHost;
class ServiceWorkerVersion;
// Roughly Corresponds to one ServiceWorkerRegistration object in the renderer
// process (WebServiceWorkerRegistrationImpl).
// Has references to the corresponding ServiceWorkerRegistration and
// ServiceWorkerVersions (therefore they're guaranteed to be alive while this
// handle is around).
class ServiceWorkerRegistrationHandle
: public ServiceWorkerRegistration::Listener {
public:
ServiceWorkerRegistrationHandle(
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerDispatcherHost* dispatcher_host,
int provider_id,
ServiceWorkerRegistration* registration);
virtual ~ServiceWorkerRegistrationHandle();
bool HasNoRefCount() const { return ref_count_ <= 0; }
void IncrementRefCount();
void DecrementRefCount();
int provider_id() const { return provider_id_; }
int handle_id() const { return handle_id_; }
ServiceWorkerRegistration* registration() { return registration_.get(); }
private:
// ServiceWorkerRegistration::Listener overrides.
virtual void OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
ChangedVersionAttributesMask changed_mask,
const ServiceWorkerRegistrationInfo& info) OVERRIDE;
virtual void OnRegistrationFailed(
ServiceWorkerRegistration* registration) OVERRIDE;
// Sets the corresponding version field to the given version or if the given
// version is NULL, clears the field.
void SetVersionAttributes(
ServiceWorkerVersion* installing_version,
ServiceWorkerVersion* waiting_version,
ServiceWorkerVersion* active_version);
// Clears all version fields.
void ClearVersionAttributes();
ServiceWorkerObjectInfo CreateServiceWorkerHandleAndPass(
ServiceWorkerVersion* version);
base::WeakPtr<ServiceWorkerContextCore> context_;
ServiceWorkerDispatcherHost* dispatcher_host_;
const int provider_id_;
const int handle_id_;
int ref_count_; // Created with 1.
scoped_refptr<ServiceWorkerRegistration> registration_;
scoped_refptr<ServiceWorkerVersion> installing_version_;
scoped_refptr<ServiceWorkerVersion> waiting_version_;
scoped_refptr<ServiceWorkerVersion> active_version_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistrationHandle);
};
} // namespace content
#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_H_
...@@ -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_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/service_worker/web_service_worker_registration_impl.h"
#include "content/child/thread_safe_sender.h" #include "content/child/thread_safe_sender.h"
...@@ -202,9 +203,43 @@ WebServiceWorkerImpl* ServiceWorkerDispatcher::GetServiceWorker( ...@@ -202,9 +203,43 @@ WebServiceWorkerImpl* ServiceWorkerDispatcher::GetServiceWorker(
return new WebServiceWorkerImpl(handle_ref.Pass(), thread_safe_sender_); return new WebServiceWorkerImpl(handle_ref.Pass(), thread_safe_sender_);
} }
WebServiceWorkerRegistrationImpl*
ServiceWorkerDispatcher::GetServiceWorkerRegistration(
int registration_handle_id,
const ServiceWorkerObjectInfo& info,
bool adopt_handle) {
if (registration_handle_id == kInvalidServiceWorkerRegistrationHandleId)
return NULL;
RegistrationObjectMap::iterator existing_registration =
registrations_.find(registration_handle_id);
if (existing_registration != registrations_.end()) {
if (adopt_handle) {
// We are instructed to adopt a handle but we already have one, so
// adopt and destroy a handle ref.
ServiceWorkerRegistrationHandleReference::Adopt(
registration_handle_id, info, thread_safe_sender_);
}
return existing_registration->second;
}
scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref =
adopt_handle
? ServiceWorkerRegistrationHandleReference::Adopt(
registration_handle_id, info, thread_safe_sender_)
: ServiceWorkerRegistrationHandleReference::Create(
registration_handle_id, info, thread_safe_sender_);
// WebServiceWorkerRegistrationImpl constructor calls
// AddServiceWorkerRegistration.
return new WebServiceWorkerRegistrationImpl(handle_ref.Pass());
}
void ServiceWorkerDispatcher::OnRegistered( void ServiceWorkerDispatcher::OnRegistered(
int thread_id, int thread_id,
int request_id, int request_id,
int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
WebServiceWorkerRegistrationCallbacks* callbacks = WebServiceWorkerRegistrationCallbacks* callbacks =
pending_callbacks_.Lookup(request_id); pending_callbacks_.Lookup(request_id);
...@@ -214,8 +249,14 @@ void ServiceWorkerDispatcher::OnRegistered( ...@@ -214,8 +249,14 @@ void ServiceWorkerDispatcher::OnRegistered(
#ifdef DISABLE_SERVICE_WORKER_REGISTRATION #ifdef DISABLE_SERVICE_WORKER_REGISTRATION
callbacks->onSuccess(GetServiceWorker(info, true)); callbacks->onSuccess(GetServiceWorker(info, true));
// We should adopt and destroy an unused handle ref.
ServiceWorkerRegistrationHandleReference::Adopt(
registration_handle_id, info, thread_safe_sender_);
#else #else
callbacks->onSuccess(new WebServiceWorkerRegistrationImpl(info)); callbacks->onSuccess(GetServiceWorkerRegistration(
registration_handle_id, info, true));
// We should adopt and destroy an unused handle ref.
ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
#endif #endif
pending_callbacks_.Remove(request_id); pending_callbacks_.Remove(request_id);
} }
...@@ -266,19 +307,30 @@ void ServiceWorkerDispatcher::OnServiceWorkerStateChanged( ...@@ -266,19 +307,30 @@ void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
void ServiceWorkerDispatcher::OnSetVersionAttributes( void ServiceWorkerDispatcher::OnSetVersionAttributes(
int thread_id, int thread_id,
int provider_id, int provider_id,
int registration_handle_id,
int changed_mask, int changed_mask,
const ServiceWorkerVersionAttributes& attributes) { const ServiceWorkerVersionAttributes& attributes) {
ChangedVersionAttributesMask mask(changed_mask); ChangedVersionAttributesMask mask(changed_mask);
if (mask.installing_changed()) if (mask.installing_changed()) {
SetInstallingServiceWorker(provider_id, attributes.installing); SetInstallingServiceWorker(provider_id,
if (mask.waiting_changed()) registration_handle_id,
SetWaitingServiceWorker(provider_id, attributes.waiting); attributes.installing);
if (mask.active_changed()) }
SetActiveServiceWorker(provider_id, attributes.active); if (mask.waiting_changed()) {
SetWaitingServiceWorker(provider_id,
registration_handle_id,
attributes.waiting);
}
if (mask.active_changed()) {
SetActiveServiceWorker(provider_id,
registration_handle_id,
attributes.active);
}
} }
void ServiceWorkerDispatcher::SetInstallingServiceWorker( void ServiceWorkerDispatcher::SetInstallingServiceWorker(
int provider_id, int provider_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()) {
...@@ -296,15 +348,26 @@ void ServiceWorkerDispatcher::SetInstallingServiceWorker( ...@@ -296,15 +348,26 @@ void ServiceWorkerDispatcher::SetInstallingServiceWorker(
worker_to_provider_[info.handle_id] = provider->second; worker_to_provider_[info.handle_id] = provider->second;
} }
#ifdef DISABLE_SERVICE_WORKER_REGISTRATION
ScriptClientMap::iterator found = script_clients_.find(provider_id); ScriptClientMap::iterator found = script_clients_.find(provider_id);
if (found != script_clients_.end()) { if (found != script_clients_.end()) {
// Populate the .installing field with the new worker object. // Populate the .installing field with the new worker object.
found->second->setInstalling(GetServiceWorker(info, false)); found->second->setInstalling(GetServiceWorker(info, false));
} }
#else
RegistrationObjectMap::iterator found =
registrations_.find(registration_handle_id);
if (found != registrations_.end()) {
found->second->setInstalling(GetServiceWorker(info, false));
if (info.handle_id != kInvalidServiceWorkerHandleId)
found->second->OnUpdateFound();
}
#endif
} }
void ServiceWorkerDispatcher::SetWaitingServiceWorker( void ServiceWorkerDispatcher::SetWaitingServiceWorker(
int provider_id, int provider_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()) {
...@@ -322,15 +385,23 @@ void ServiceWorkerDispatcher::SetWaitingServiceWorker( ...@@ -322,15 +385,23 @@ void ServiceWorkerDispatcher::SetWaitingServiceWorker(
worker_to_provider_[info.handle_id] = provider->second; worker_to_provider_[info.handle_id] = provider->second;
} }
#ifdef DISABLE_SERVICE_WORKER_REGISTRATION
ScriptClientMap::iterator found = script_clients_.find(provider_id); ScriptClientMap::iterator found = script_clients_.find(provider_id);
if (found != script_clients_.end()) { if (found != script_clients_.end()) {
// Populate the .waiting field with the new worker object. // Populate the .waiting field with the new worker object.
found->second->setWaiting(GetServiceWorker(info, false)); found->second->setWaiting(GetServiceWorker(info, false));
} }
#else
RegistrationObjectMap::iterator found =
registrations_.find(registration_handle_id);
if (found != registrations_.end())
found->second->setWaiting(GetServiceWorker(info, false));
#endif
} }
void ServiceWorkerDispatcher::SetActiveServiceWorker( void ServiceWorkerDispatcher::SetActiveServiceWorker(
int provider_id, int provider_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()) {
...@@ -348,11 +419,18 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker( ...@@ -348,11 +419,18 @@ void ServiceWorkerDispatcher::SetActiveServiceWorker(
worker_to_provider_[info.handle_id] = provider->second; worker_to_provider_[info.handle_id] = provider->second;
} }
#ifdef DISABLE_SERVICE_WORKER_REGISTRATION
ScriptClientMap::iterator found = script_clients_.find(provider_id); ScriptClientMap::iterator found = script_clients_.find(provider_id);
if (found != script_clients_.end()) { if (found != script_clients_.end()) {
// Populate the .active field with the new worker object. // Populate the .active field with the new worker object.
found->second->setActive(GetServiceWorker(info, false)); found->second->setActive(GetServiceWorker(info, false));
} }
#else
RegistrationObjectMap::iterator found =
registrations_.find(registration_handle_id);
if (found != registrations_.end())
found->second->setActive(GetServiceWorker(info, false));
#endif
} }
void ServiceWorkerDispatcher::OnSetControllerServiceWorker( void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
...@@ -413,4 +491,17 @@ void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) { ...@@ -413,4 +491,17 @@ void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) {
service_workers_.erase(handle_id); service_workers_.erase(handle_id);
} }
void ServiceWorkerDispatcher::AddServiceWorkerRegistration(
int registration_handle_id,
WebServiceWorkerRegistrationImpl* registration) {
DCHECK(!ContainsKey(registrations_, registration_handle_id));
registrations_[registration_handle_id] = registration;
}
void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration(
int registration_handle_id) {
DCHECK(ContainsKey(registrations_, registration_handle_id));
registrations_.erase(registration_handle_id);
}
} // namespace content } // namespace content
...@@ -32,6 +32,7 @@ class ServiceWorkerMessageFilter; ...@@ -32,6 +32,7 @@ class ServiceWorkerMessageFilter;
class ServiceWorkerProviderContext; class ServiceWorkerProviderContext;
class ThreadSafeSender; class ThreadSafeSender;
class WebServiceWorkerImpl; class WebServiceWorkerImpl;
class WebServiceWorkerRegistrationImpl;
struct ServiceWorkerObjectInfo; struct ServiceWorkerObjectInfo;
struct ServiceWorkerVersionAttributes; struct ServiceWorkerVersionAttributes;
...@@ -87,8 +88,19 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -87,8 +88,19 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
// WebServiceWorkerImpl, in which case ownership is transferred to // WebServiceWorkerImpl, in which case ownership is transferred to
// the caller who must bounce it to a method that will associate it // the caller who must bounce it to a method that will associate it
// with a WebCore::ServiceWorker. // with a WebCore::ServiceWorker.
WebServiceWorkerImpl* GetServiceWorker(const ServiceWorkerObjectInfo&, WebServiceWorkerImpl* GetServiceWorker(
bool adopt_handle); const ServiceWorkerObjectInfo& info,
bool adopt_handle);
// If an existing WebServiceWorkerRegistrationImpl exists for the
// registration, it is returned; otherwise a WebServiceWorkerRegistrationImpl
// is created and its ownership is transferred to the caller. If
// |adopt_handle| is true, a ServiceWorkerRegistrationHandleReference will be
// adopted for the specified registration.
WebServiceWorkerRegistrationImpl* GetServiceWorkerRegistration(
int registration_handle_id,
const ServiceWorkerObjectInfo& info,
bool adopt_handle);
// |thread_safe_sender| needs to be passed in because if the call leads to // |thread_safe_sender| needs to be passed in because if the call leads to
// construction it will be needed. // construction it will be needed.
...@@ -106,14 +118,18 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -106,14 +118,18 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
typedef std::map<int, ServiceWorkerProviderContext*> ProviderContextMap; typedef std::map<int, ServiceWorkerProviderContext*> ProviderContextMap;
typedef std::map<int, WebServiceWorkerImpl*> WorkerObjectMap; typedef std::map<int, WebServiceWorkerImpl*> WorkerObjectMap;
typedef std::map<int, ServiceWorkerProviderContext*> WorkerToProviderMap; typedef std::map<int, ServiceWorkerProviderContext*> WorkerToProviderMap;
typedef std::map<int, WebServiceWorkerRegistrationImpl*>
RegistrationObjectMap;
friend class WebServiceWorkerImpl; friend class WebServiceWorkerImpl;
friend class WebServiceWorkerRegistrationImpl;
// WorkerTaskRunner::Observer implementation. // WorkerTaskRunner::Observer implementation.
virtual void OnWorkerRunLoopStopped() OVERRIDE; virtual void OnWorkerRunLoopStopped() OVERRIDE;
void OnRegistered(int thread_id, void OnRegistered(int thread_id,
int request_id, int request_id,
int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void OnUnregistered(int thread_id, void OnUnregistered(int thread_id,
int request_id); int request_id);
...@@ -126,6 +142,7 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -126,6 +142,7 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
blink::WebServiceWorkerState state); blink::WebServiceWorkerState state);
void OnSetVersionAttributes(int thread_id, void OnSetVersionAttributes(int thread_id,
int provider_id, int provider_id,
int registration_handle_id,
int changed_mask, int changed_mask,
const ServiceWorkerVersionAttributes& attributes); const ServiceWorkerVersionAttributes& attributes);
void OnSetControllerServiceWorker(int thread_id, void OnSetControllerServiceWorker(int thread_id,
...@@ -139,22 +156,33 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { ...@@ -139,22 +156,33 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer {
void SetInstallingServiceWorker( void SetInstallingServiceWorker(
int provider_id, int provider_id,
int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void SetWaitingServiceWorker( void SetWaitingServiceWorker(
int provider_id, int provider_id,
int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void SetActiveServiceWorker( void SetActiveServiceWorker(
int provider_id, int provider_id,
int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
// 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);
void RemoveServiceWorker(int handle_id); void RemoveServiceWorker(int handle_id);
// Keeps map from registration_handle_id to ServiceWorkerRegistration object.
void AddServiceWorkerRegistration(
int registration_handle_id,
WebServiceWorkerRegistrationImpl* registration);
void RemoveServiceWorkerRegistration(
int registration_handle_id);
CallbackMap pending_callbacks_; CallbackMap pending_callbacks_;
ScriptClientMap script_clients_; ScriptClientMap script_clients_;
ProviderContextMap provider_contexts_; ProviderContextMap provider_contexts_;
WorkerObjectMap service_workers_; WorkerObjectMap service_workers_;
RegistrationObjectMap registrations_;
// A map for ServiceWorkers that are associated to a particular document // A map for ServiceWorkers that are associated to a particular document
// (e.g. as .current). // (e.g. as .current).
......
...@@ -19,7 +19,7 @@ namespace { ...@@ -19,7 +19,7 @@ namespace {
// Sends a ServiceWorkerObjectDestroyed message to the browser so it can delete // Sends a ServiceWorkerObjectDestroyed message to the browser so it can delete
// the ServiceWorker handle. // the ServiceWorker handle.
void SendServiceWorkerObjectDestroyed( void SendServiceWorkerObjectDestroyed(
scoped_refptr<ThreadSafeSender> sender, ThreadSafeSender* sender,
int handle_id) { int handle_id) {
if (handle_id == kInvalidServiceWorkerHandleId) if (handle_id == kInvalidServiceWorkerHandleId)
return; return;
...@@ -27,6 +27,15 @@ void SendServiceWorkerObjectDestroyed( ...@@ -27,6 +27,15 @@ void SendServiceWorkerObjectDestroyed(
new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(handle_id)); new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount(handle_id));
} }
void SendRegistrationObjectDestroyed(
ThreadSafeSender* sender,
int handle_id) {
if (handle_id == kInvalidServiceWorkerRegistrationHandleId)
return;
sender->Send(
new ServiceWorkerHostMsg_DecrementRegistrationRefCount(handle_id));
}
} // namespace } // namespace
ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender) ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(ThreadSafeSender* sender)
...@@ -72,13 +81,16 @@ void ServiceWorkerMessageFilter::OnStaleMessageReceived( ...@@ -72,13 +81,16 @@ void ServiceWorkerMessageFilter::OnStaleMessageReceived(
void ServiceWorkerMessageFilter::OnStaleRegistered( void ServiceWorkerMessageFilter::OnStaleRegistered(
int thread_id, int thread_id,
int request_id, int request_id,
int registration_handle_id,
const ServiceWorkerObjectInfo& info) { const ServiceWorkerObjectInfo& info) {
SendServiceWorkerObjectDestroyed(thread_safe_sender_, info.handle_id); SendServiceWorkerObjectDestroyed(thread_safe_sender_, info.handle_id);
SendRegistrationObjectDestroyed(thread_safe_sender_, registration_handle_id);
} }
void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes( void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes(
int thread_id, int thread_id,
int provider_id, int provider_id,
int registration_handle_id,
int changed_mask, int changed_mask,
const ServiceWorkerVersionAttributes& attributes) { const ServiceWorkerVersionAttributes& attributes) {
SendServiceWorkerObjectDestroyed(thread_safe_sender_, SendServiceWorkerObjectDestroyed(thread_safe_sender_,
...@@ -87,6 +99,7 @@ void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes( ...@@ -87,6 +99,7 @@ void ServiceWorkerMessageFilter::OnStaleSetVersionAttributes(
attributes.waiting.handle_id); attributes.waiting.handle_id);
SendServiceWorkerObjectDestroyed(thread_safe_sender_, SendServiceWorkerObjectDestroyed(thread_safe_sender_,
attributes.active.handle_id); attributes.active.handle_id);
SendRegistrationObjectDestroyed(thread_safe_sender_, registration_handle_id);
} }
void ServiceWorkerMessageFilter::OnStaleSetControllerServiceWorker( void ServiceWorkerMessageFilter::OnStaleSetControllerServiceWorker(
......
...@@ -37,10 +37,12 @@ class CONTENT_EXPORT ServiceWorkerMessageFilter ...@@ -37,10 +37,12 @@ class CONTENT_EXPORT ServiceWorkerMessageFilter
void OnStaleRegistered( void OnStaleRegistered(
int thread_id, int thread_id,
int request_id, int request_id,
int registration_handle_id,
const ServiceWorkerObjectInfo& info); const ServiceWorkerObjectInfo& info);
void OnStaleSetVersionAttributes( void OnStaleSetVersionAttributes(
int thread_id, int thread_id,
int provider_id, int provider_id,
int registration_handle_id,
int changed_mask, int changed_mask,
const ServiceWorkerVersionAttributes& attributes); const ServiceWorkerVersionAttributes& attributes);
void OnStaleSetControllerServiceWorker( void OnStaleSetControllerServiceWorker(
......
// 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/child/service_worker/service_worker_registration_handle_reference.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_types.h"
namespace content {
scoped_ptr<ServiceWorkerRegistrationHandleReference>
ServiceWorkerRegistrationHandleReference::Create(
int registration_handle_id,
const ServiceWorkerObjectInfo& info,
ThreadSafeSender* sender) {
return make_scoped_ptr(new ServiceWorkerRegistrationHandleReference(
registration_handle_id, info, sender, true));
}
scoped_ptr<ServiceWorkerRegistrationHandleReference>
ServiceWorkerRegistrationHandleReference::Adopt(
int registration_handle_id,
const ServiceWorkerObjectInfo& info,
ThreadSafeSender* sender) {
return make_scoped_ptr(new ServiceWorkerRegistrationHandleReference(
registration_handle_id, info, sender, false));
}
ServiceWorkerRegistrationHandleReference::
ServiceWorkerRegistrationHandleReference(
int registration_handle_id,
const ServiceWorkerObjectInfo& info,
ThreadSafeSender* sender,
bool increment_ref_in_ctor)
: handle_id_(registration_handle_id),
scope_(info.scope),
sender_(sender) {
DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId, handle_id_);
DCHECK(sender_);
if (increment_ref_in_ctor)
return;
sender_->Send(
new ServiceWorkerHostMsg_IncrementRegistrationRefCount(handle_id_));
}
ServiceWorkerRegistrationHandleReference::
~ServiceWorkerRegistrationHandleReference() {
sender_->Send(
new ServiceWorkerHostMsg_DecrementRegistrationRefCount(handle_id_));
}
} // 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_CHILD_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_REFERENCE_H_
#define CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_REFERENCE_H_
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "url/gurl.h"
namespace content {
class ThreadSafeSender;
struct ServiceWorkerObjectInfo;
class ServiceWorkerRegistrationHandleReference {
public:
// Creates a new ServiceWorkerRegistrationHandleReference and increments
// ref-count.
static scoped_ptr<ServiceWorkerRegistrationHandleReference> Create(
int registration_handle_id,
const ServiceWorkerObjectInfo& info,
ThreadSafeSender* sender);
// Creates a new ServiceWorkerRegistrationHandleReference by adopting a
// ref-count.
static scoped_ptr<ServiceWorkerRegistrationHandleReference> Adopt(
int registration_handle_id,
const ServiceWorkerObjectInfo& info,
ThreadSafeSender* sender);
~ServiceWorkerRegistrationHandleReference();
int handle_id() const { return handle_id_; }
GURL scope() const { return scope_; }
private:
ServiceWorkerRegistrationHandleReference(int registration_handle_id,
const ServiceWorkerObjectInfo& info,
ThreadSafeSender* sender,
bool increment_ref_in_ctor);
const int handle_id_;
const GURL scope_;
scoped_refptr<ThreadSafeSender> sender_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegistrationHandleReference);
};
} // namespace content
#endif // CONTENT_CHILD_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_HANDLE_REFERENCE_H_
...@@ -4,20 +4,63 @@ ...@@ -4,20 +4,63 @@
#include "content/child/service_worker/web_service_worker_registration_impl.h" #include "content/child/service_worker/web_service_worker_registration_impl.h"
#include "content/child/service_worker/service_worker_dispatcher.h"
#include "content/child/service_worker/service_worker_registration_handle_reference.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"
namespace content { namespace content {
WebServiceWorkerRegistrationImpl::WebServiceWorkerRegistrationImpl( WebServiceWorkerRegistrationImpl::WebServiceWorkerRegistrationImpl(
const ServiceWorkerObjectInfo& info) scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref)
: scope_(info.scope) { : handle_ref_(handle_ref.Pass()),
proxy_(NULL) {
DCHECK(handle_ref_);
DCHECK_NE(kInvalidServiceWorkerRegistrationHandleId,
handle_ref_->handle_id());
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
DCHECK(dispatcher);
dispatcher->AddServiceWorkerRegistration(handle_ref_->handle_id(), this);
} }
WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() { WebServiceWorkerRegistrationImpl::~WebServiceWorkerRegistrationImpl() {
ServiceWorkerDispatcher* dispatcher =
ServiceWorkerDispatcher::GetThreadSpecificInstance();
if (dispatcher)
dispatcher->RemoveServiceWorkerRegistration(handle_ref_->handle_id());
}
void WebServiceWorkerRegistrationImpl::OnUpdateFound() {
DCHECK(proxy_);
proxy_->dispatchUpdateFoundEvent();
}
void WebServiceWorkerRegistrationImpl::setProxy(
blink::WebServiceWorkerRegistrationProxy* proxy) {
proxy_ = proxy;
}
void WebServiceWorkerRegistrationImpl::setInstalling(
blink::WebServiceWorker* service_worker) {
DCHECK(proxy_);
proxy_->setInstalling(service_worker);
}
void WebServiceWorkerRegistrationImpl::setWaiting(
blink::WebServiceWorker* service_worker) {
DCHECK(proxy_);
proxy_->setWaiting(service_worker);
}
void WebServiceWorkerRegistrationImpl::setActive(
blink::WebServiceWorker* service_worker) {
DCHECK(proxy_);
proxy_->setActive(service_worker);
} }
blink::WebURL WebServiceWorkerRegistrationImpl::scope() const { blink::WebURL WebServiceWorkerRegistrationImpl::scope() const {
return scope_; return handle_ref_->scope();
} }
} // namespace content } // namespace content
...@@ -8,21 +8,36 @@ ...@@ -8,21 +8,36 @@
#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"
namespace blink {
class WebServiceWorker;
class WebServiceWorkerRegistrationProxy;
}
namespace content { namespace content {
class ServiceWorkerRegistrationHandleReference;
class ThreadSafeSender;
struct ServiceWorkerObjectInfo; struct ServiceWorkerObjectInfo;
class WebServiceWorkerRegistrationImpl class WebServiceWorkerRegistrationImpl
: NON_EXPORTED_BASE(public blink::WebServiceWorkerRegistration) { : NON_EXPORTED_BASE(public blink::WebServiceWorkerRegistration) {
public: public:
explicit WebServiceWorkerRegistrationImpl( explicit WebServiceWorkerRegistrationImpl(
const ServiceWorkerObjectInfo& info); scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref);
virtual ~WebServiceWorkerRegistrationImpl(); virtual ~WebServiceWorkerRegistrationImpl();
void OnUpdateFound();
virtual void setProxy(blink::WebServiceWorkerRegistrationProxy* proxy);
virtual void setInstalling(blink::WebServiceWorker* service_worker);
virtual void setWaiting(blink::WebServiceWorker* service_worker);
virtual void setActive(blink::WebServiceWorker* service_worker);
virtual blink::WebURL scope() const; virtual blink::WebURL scope() const;
private: private:
const GURL scope_; scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref_;
blink::WebServiceWorkerRegistrationProxy* proxy_;
DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerRegistrationImpl); DISALLOW_COPY_AND_ASSIGN(WebServiceWorkerRegistrationImpl);
}; };
......
...@@ -102,8 +102,16 @@ IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderDestroyed, ...@@ -102,8 +102,16 @@ IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_ProviderDestroyed,
// counting in the browser side. The ServiceWorker object is created // counting in the browser side. The ServiceWorker object is created
// with ref-count==1 initially. // with ref-count==1 initially.
IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount, IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount,
int /* handle_id */) int /* registration_handle_id */)
IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount, IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount,
int /* registration_handle_id */)
// Increments and decrements the ServiceWorkerRegistration object's reference
// counting in the browser side. The registration object is created with
// ref-count==1 initially.
IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_IncrementRegistrationRefCount,
int /* handle_id */)
IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_DecrementRegistrationRefCount,
int /* handle_id */) int /* handle_id */)
// Informs the browser that |provider_id| is associated // Informs the browser that |provider_id| is associated
...@@ -170,9 +178,10 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_CacheStorageKeys, ...@@ -170,9 +178,10 @@ IPC_MESSAGE_ROUTED1(ServiceWorkerHostMsg_CacheStorageKeys,
// on the correct thread. // on the correct thread.
// Response to ServiceWorkerMsg_RegisterServiceWorker. // Response to ServiceWorkerMsg_RegisterServiceWorker.
IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_ServiceWorkerRegistered, IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_ServiceWorkerRegistered,
int /* thread_id */, int /* thread_id */,
int /* request_id */, int /* request_id */,
int /* registration_handle_id */,
content::ServiceWorkerObjectInfo) content::ServiceWorkerObjectInfo)
// Response to ServiceWorkerMsg_UnregisterServiceWorker. // Response to ServiceWorkerMsg_UnregisterServiceWorker.
...@@ -195,9 +204,10 @@ IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_ServiceWorkerStateChanged, ...@@ -195,9 +204,10 @@ IPC_MESSAGE_CONTROL3(ServiceWorkerMsg_ServiceWorkerStateChanged,
blink::WebServiceWorkerState) blink::WebServiceWorkerState)
// Tells the child process to set service workers for the given provider. // Tells the child process to set service workers for the given provider.
IPC_MESSAGE_CONTROL4(ServiceWorkerMsg_SetVersionAttributes, IPC_MESSAGE_CONTROL5(ServiceWorkerMsg_SetVersionAttributes,
int /* thread_id */, int /* thread_id */,
int /* provider_id */, int /* provider_id */,
int /* registration_handle_id */,
int /* changed_mask */, int /* changed_mask */,
content::ServiceWorkerVersionAttributes) content::ServiceWorkerVersionAttributes)
......
...@@ -25,6 +25,7 @@ static const int kInvalidServiceWorkerRequestId = -1; ...@@ -25,6 +25,7 @@ static const int kInvalidServiceWorkerRequestId = -1;
// Constants for invalid identifiers. // Constants for invalid identifiers.
static const int kInvalidServiceWorkerHandleId = -1; static const int kInvalidServiceWorkerHandleId = -1;
static const int kInvalidServiceWorkerRegistrationHandleId = -1;
static const int kInvalidServiceWorkerProviderId = -1; static const int kInvalidServiceWorkerProviderId = -1;
static const int64 kInvalidServiceWorkerRegistrationId = -1; static const int64 kInvalidServiceWorkerRegistrationId = -1;
static const int64 kInvalidServiceWorkerVersionId = -1; static const int64 kInvalidServiceWorkerVersionId = -1;
......
...@@ -1170,6 +1170,8 @@ ...@@ -1170,6 +1170,8 @@
'browser/service_worker/service_worker_register_job.h', 'browser/service_worker/service_worker_register_job.h',
'browser/service_worker/service_worker_registration.cc', 'browser/service_worker/service_worker_registration.cc',
'browser/service_worker/service_worker_registration.h', 'browser/service_worker/service_worker_registration.h',
'browser/service_worker/service_worker_registration_handle.cc',
'browser/service_worker/service_worker_registration_handle.h',
'browser/service_worker/service_worker_registration_status.cc', 'browser/service_worker/service_worker_registration_status.cc',
'browser/service_worker/service_worker_registration_status.h', 'browser/service_worker/service_worker_registration_status.h',
'browser/service_worker/service_worker_request_handler.cc', 'browser/service_worker/service_worker_request_handler.cc',
......
...@@ -165,6 +165,8 @@ ...@@ -165,6 +165,8 @@
'child/service_worker/service_worker_network_provider.h', 'child/service_worker/service_worker_network_provider.h',
'child/service_worker/service_worker_provider_context.cc', 'child/service_worker/service_worker_provider_context.cc',
'child/service_worker/service_worker_provider_context.h', 'child/service_worker/service_worker_provider_context.h',
'child/service_worker/service_worker_registration_handle_reference.cc',
'child/service_worker/service_worker_registration_handle_reference.h',
'child/service_worker/web_service_worker_impl.cc', 'child/service_worker/web_service_worker_impl.cc',
'child/service_worker/web_service_worker_impl.h', 'child/service_worker/web_service_worker_impl.h',
'child/service_worker/web_service_worker_provider_impl.cc', 'child/service_worker/web_service_worker_provider_impl.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