diff options
author | ksakamoto <ksakamoto@chromium.org> | 2014-09-12 18:18:44 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-13 01:21:43 +0000 |
commit | 0d1c4968ac6d14ee8d250df9641b6434eb9aaaf0 (patch) | |
tree | 48c1cdfcaceaa0de5a92ec3d6ab60502a3119d1a /content/child/service_worker | |
parent | fecaedc03904c091897dea2926ec00756f6e53ed (diff) | |
download | chromium_src-0d1c4968ac6d14ee8d250df9641b6434eb9aaaf0.zip chromium_src-0d1c4968ac6d14ee8d250df9641b6434eb9aaaf0.tar.gz chromium_src-0d1c4968ac6d14ee8d250df9641b6434eb9aaaf0.tar.bz2 |
ServiceWorker: Implement navigator.serviceWorker.getRegistration [2/3]
This patch implements the Chromium-side change of
ServiceWorkerContainer#getRegistration().
Spec: https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#navigator-service-worker-getRegistration
[1/3] https://codereview.chromium.org/553983010/
[3/3] https://codereview.chromium.org/540823003/
BUG=404951
TEST=content_unittests
Review URL: https://codereview.chromium.org/535753002
Cr-Commit-Position: refs/heads/master@{#294720}
Diffstat (limited to 'content/child/service_worker')
4 files changed, 138 insertions, 19 deletions
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc index df616df..4ebb9ed 100644 --- a/content/child/service_worker/service_worker_dispatcher.cc +++ b/content/child/service_worker/service_worker_dispatcher.cc @@ -61,10 +61,14 @@ void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, OnRegistered) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered, OnUnregistered) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_DidGetRegistration, + OnDidGetRegistration) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError, OnRegistrationError) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistrationError, OnUnregistrationError) + IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerGetRegistrationError, + OnGetRegistrationError) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged, OnServiceWorkerStateChanged) IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes, @@ -135,6 +139,30 @@ void ServiceWorkerDispatcher::UnregisterServiceWorker( CurrentWorkerId(), request_id, provider_id, pattern)); } +void ServiceWorkerDispatcher::GetRegistration( + int provider_id, + const GURL& document_url, + WebServiceWorkerRegistrationCallbacks* callbacks) { + DCHECK(callbacks); + + if (document_url.possibly_invalid_spec().size() > GetMaxURLChars()) { + scoped_ptr<WebServiceWorkerRegistrationCallbacks> + owned_callbacks(callbacks); + scoped_ptr<WebServiceWorkerError> error(new WebServiceWorkerError( + WebServiceWorkerError::ErrorTypeSecurity, "URL too long")); + callbacks->onError(error.release()); + return; + } + + int request_id = pending_get_registration_callbacks_.Add(callbacks); + TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", + "ServiceWorkerDispatcher::GetRegistration", + request_id, + "Document URL", document_url.spec()); + thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistration( + CurrentWorkerId(), request_id, provider_id, document_url)); +} + void ServiceWorkerDispatcher::AddProviderContext( ServiceWorkerProviderContext* provider_context) { DCHECK(provider_context); @@ -303,25 +331,7 @@ void ServiceWorkerDispatcher::OnRegistered( if (!callbacks) return; - WebServiceWorkerRegistrationImpl* registration = - FindServiceWorkerRegistration(info, true); - if (!registration) { - registration = CreateServiceWorkerRegistration(info, true); - registration->SetInstalling(GetServiceWorker(attrs.installing, true)); - registration->SetWaiting(GetServiceWorker(attrs.waiting, 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(FindOrCreateRegistration(info, attrs)); pending_registration_callbacks_.Remove(request_id); TRACE_EVENT_ASYNC_END0("ServiceWorker", "ServiceWorkerDispatcher::RegisterServiceWorker", @@ -348,6 +358,33 @@ void ServiceWorkerDispatcher::OnUnregistered(int thread_id, request_id); } +void ServiceWorkerDispatcher::OnDidGetRegistration( + int thread_id, + int request_id, + const ServiceWorkerRegistrationObjectInfo& info, + const ServiceWorkerVersionAttributes& attrs) { + WebServiceWorkerRegistrationCallbacks* callbacks = + pending_get_registration_callbacks_.Lookup(request_id); + TRACE_EVENT_ASYNC_STEP_INTO0( + "ServiceWorker", + "ServiceWorkerDispatcher::GetRegistration", + request_id, + "OnDidGetRegistration"); + DCHECK(callbacks); + if (!callbacks) + return; + + WebServiceWorkerRegistrationImpl* registration = NULL; + if (info.handle_id != kInvalidServiceWorkerHandleId) + registration = FindOrCreateRegistration(info, attrs); + + callbacks->onSuccess(registration); + pending_get_registration_callbacks_.Remove(request_id); + TRACE_EVENT_ASYNC_END0("ServiceWorker", + "ServiceWorkerDispatcher::GetRegistration", + request_id); +} + void ServiceWorkerDispatcher::OnRegistrationError( int thread_id, int request_id, @@ -397,6 +434,31 @@ void ServiceWorkerDispatcher::OnUnregistrationError( request_id); } +void ServiceWorkerDispatcher::OnGetRegistrationError( + int thread_id, + int request_id, + WebServiceWorkerError::ErrorType error_type, + const base::string16& message) { + TRACE_EVENT_ASYNC_STEP_INTO0( + "ServiceWorker", + "ServiceWorkerDispatcher::GetRegistration", + request_id, + "OnGetRegistrationError"); + WebServiceWorkerGetRegistrationCallbacks* callbacks = + pending_get_registration_callbacks_.Lookup(request_id); + DCHECK(callbacks); + if (!callbacks) + return; + + scoped_ptr<WebServiceWorkerError> error( + new WebServiceWorkerError(error_type, message)); + callbacks->onError(error.release()); + pending_get_registration_callbacks_.Remove(request_id); + TRACE_EVENT_ASYNC_END0("ServiceWorker", + "ServiceWorkerDispatcher::GetRegistration", + request_id); +} + void ServiceWorkerDispatcher::OnServiceWorkerStateChanged( int thread_id, int handle_id, @@ -650,4 +712,28 @@ void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration( registrations_.erase(registration_handle_id); } +WebServiceWorkerRegistrationImpl* +ServiceWorkerDispatcher::FindOrCreateRegistration( + const ServiceWorkerRegistrationObjectInfo& info, + const ServiceWorkerVersionAttributes& attrs) { + WebServiceWorkerRegistrationImpl* registration = + FindServiceWorkerRegistration(info, true); + if (!registration) { + registration = CreateServiceWorkerRegistration(info, true); + registration->SetInstalling(GetServiceWorker(attrs.installing, true)); + registration->SetWaiting(GetServiceWorker(attrs.waiting, 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()); + } + return registration; +} + } // namespace content diff --git a/content/child/service_worker/service_worker_dispatcher.h b/content/child/service_worker/service_worker_dispatcher.h index 80ae40a..742c4d7 100644 --- a/content/child/service_worker/service_worker_dispatcher.h +++ b/content/child/service_worker/service_worker_dispatcher.h @@ -47,6 +47,9 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { typedef blink::WebServiceWorkerProvider::WebServiceWorkerUnregistrationCallbacks WebServiceWorkerUnregistrationCallbacks; + typedef + blink::WebServiceWorkerProvider::WebServiceWorkerGetRegistrationCallbacks + WebServiceWorkerGetRegistrationCallbacks; explicit ServiceWorkerDispatcher(ThreadSafeSender* thread_safe_sender); virtual ~ServiceWorkerDispatcher(); @@ -65,6 +68,11 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { int provider_id, const GURL& pattern, WebServiceWorkerUnregistrationCallbacks* callbacks); + // Corresponds to navigator.serviceWorker.getRegistration() + void GetRegistration( + int provider_id, + const GURL& document_url, + WebServiceWorkerRegistrationCallbacks* callbacks); // Called when a new provider context for a document is created. Usually // this happens when a new document is being loaded, and is called much @@ -126,6 +134,8 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { IDMapOwnPointer> RegistrationCallbackMap; typedef IDMap<WebServiceWorkerUnregistrationCallbacks, IDMapOwnPointer> UnregistrationCallbackMap; + typedef IDMap<WebServiceWorkerGetRegistrationCallbacks, + IDMapOwnPointer> GetRegistrationCallbackMap; typedef std::map<int, blink::WebServiceWorkerProviderClient*> ScriptClientMap; typedef std::map<int, ServiceWorkerProviderContext*> ProviderContextMap; typedef std::map<int, WebServiceWorkerImpl*> WorkerObjectMap; @@ -152,6 +162,10 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { void OnUnregistered(int thread_id, int request_id, bool is_success); + void OnDidGetRegistration(int thread_id, + int request_id, + const ServiceWorkerRegistrationObjectInfo& info, + const ServiceWorkerVersionAttributes& attrs); void OnRegistrationError(int thread_id, int request_id, blink::WebServiceWorkerError::ErrorType error_type, @@ -160,6 +174,11 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { int request_id, blink::WebServiceWorkerError::ErrorType error_type, const base::string16& message); + void OnGetRegistrationError( + int thread_id, + int request_id, + blink::WebServiceWorkerError::ErrorType error_type, + const base::string16& message); void OnServiceWorkerStateChanged(int thread_id, int handle_id, blink::WebServiceWorkerState state); @@ -206,8 +225,13 @@ class ServiceWorkerDispatcher : public WorkerTaskRunner::Observer { void RemoveServiceWorkerRegistration( int registration_handle_id); + WebServiceWorkerRegistrationImpl* FindOrCreateRegistration( + const ServiceWorkerRegistrationObjectInfo& info, + const ServiceWorkerVersionAttributes& attrs); + RegistrationCallbackMap pending_registration_callbacks_; UnregistrationCallbackMap pending_unregistration_callbacks_; + GetRegistrationCallbackMap pending_get_registration_callbacks_; ScriptClientMap script_clients_; ProviderContextMap provider_contexts_; WorkerObjectMap service_workers_; diff --git a/content/child/service_worker/web_service_worker_provider_impl.cc b/content/child/service_worker/web_service_worker_provider_impl.cc index c416440..ef46bf8c 100644 --- a/content/child/service_worker/web_service_worker_provider_impl.cc +++ b/content/child/service_worker/web_service_worker_provider_impl.cc @@ -94,6 +94,12 @@ void WebServiceWorkerProviderImpl::unregisterServiceWorker( provider_id_, pattern, callbacks); } +void WebServiceWorkerProviderImpl::getRegistration( + const blink::WebURL& document_url, + WebServiceWorkerRegistrationCallbacks* callbacks) { + GetDispatcher()->GetRegistration(provider_id_, document_url, callbacks); +} + void WebServiceWorkerProviderImpl::RemoveScriptClient() { // Remove the script client, but only if the dispatcher is still there. // (For cleanup path we don't need to bother creating a new dispatcher) diff --git a/content/child/service_worker/web_service_worker_provider_impl.h b/content/child/service_worker/web_service_worker_provider_impl.h index e7a4a7d..e56f913 100644 --- a/content/child/service_worker/web_service_worker_provider_impl.h +++ b/content/child/service_worker/web_service_worker_provider_impl.h @@ -40,6 +40,9 @@ class WebServiceWorkerProviderImpl const blink::WebURL& pattern, WebServiceWorkerUnregistrationCallbacks*); + virtual void getRegistration(const blink::WebURL& document_url, + WebServiceWorkerGetRegistrationCallbacks*); + ServiceWorkerProviderContext* context() { return context_.get(); } int provider_id() const { return provider_id_; } |