diff options
author | jungkee.song <jungkee.song@samsung.com> | 2015-08-03 05:10:36 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-03 12:11:17 +0000 |
commit | 2f85d42e860bb2370f411a7a2d3ad665641d6970 (patch) | |
tree | bbcb564ae1e7590050e13b6d587f21636ed9d5a4 /content/browser/service_worker | |
parent | 5f207fa68d2caafcfc86eda9d6ca869bfde85203 (diff) | |
download | chromium_src-2f85d42e860bb2370f411a7a2d3ad665641d6970.zip chromium_src-2f85d42e860bb2370f411a7a2d3ad665641d6970.tar.gz chromium_src-2f85d42e860bb2370f411a7a2d3ad665641d6970.tar.bz2 |
Service Worker: Make ServiceWorkerRegistration.update() return a promise. (Chromium 2/3)
As per the resolution of f2f, ServiceWorkerRegistration.update() should return a
promise that transforms the promise returned by Update algorithm.
In this CL, ServiceWorkerContextCore::UpdateServiceWorker method has been
overloaded to cover two invocation paths: a scheduled update without a
provider_host and a callback (Soft Update in the spec) and a call initiated from
the script surface using ServiceWorkerRegistration.update().
Spec: https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#service-worker-registration-update
Spec discussion: https://github.com/slightlyoff/ServiceWorker/issues/311
Companion CL (Blink): https://codereview.chromium.org/1260833003/
Companion CL (Blink layout test): https://codereview.chromium.org/1268663003/
BUG=513655
Review URL: https://codereview.chromium.org/1270513002
Cr-Commit-Position: refs/heads/master@{#341515}
Diffstat (limited to 'content/browser/service_worker')
6 files changed, 155 insertions, 17 deletions
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc index 0416733..910fe81 100644 --- a/content/browser/service_worker/service_worker_context_core.cc +++ b/content/browser/service_worker/service_worker_context_core.cc @@ -271,6 +271,33 @@ void ServiceWorkerContextCore::RegisterServiceWorker( callback)); } +void ServiceWorkerContextCore::UpdateServiceWorker( + ServiceWorkerRegistration* registration, + bool force_bypass_cache) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (storage()->IsDisabled()) + return; + + job_coordinator_->Update(registration, force_bypass_cache); +} + +void ServiceWorkerContextCore::UpdateServiceWorker( + ServiceWorkerRegistration* registration, + bool force_bypass_cache, + ServiceWorkerProviderHost* provider_host, + const UpdateCallback& callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + if (storage()->IsDisabled()) { + callback.Run(SERVICE_WORKER_ERROR_ABORT, std::string(), + kInvalidServiceWorkerRegistrationId); + return; + } + + job_coordinator_->Update(registration, force_bypass_cache, provider_host, + base::Bind(&ServiceWorkerContextCore::UpdateComplete, + AsWeakPtr(), callback)); +} + void ServiceWorkerContextCore::UnregisterServiceWorker( const GURL& pattern, const UnregistrationCallback& callback) { @@ -325,15 +352,6 @@ void ServiceWorkerContextCore::DidGetAllRegistrationsForUnregisterForOrigin( } } -void ServiceWorkerContextCore::UpdateServiceWorker( - ServiceWorkerRegistration* registration, - bool force_bypass_cache) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (storage()->IsDisabled()) - return; - job_coordinator_->Update(registration, force_bypass_cache); -} - void ServiceWorkerContextCore::RegistrationComplete( const GURL& pattern, const ServiceWorkerContextCore::RegistrationCallback& callback, @@ -358,6 +376,21 @@ void ServiceWorkerContextCore::RegistrationComplete( } } +void ServiceWorkerContextCore::UpdateComplete( + const ServiceWorkerContextCore::UpdateCallback& callback, + ServiceWorkerStatusCode status, + const std::string& status_message, + ServiceWorkerRegistration* registration) { + if (status != SERVICE_WORKER_OK) { + DCHECK(!registration); + callback.Run(status, status_message, kInvalidServiceWorkerRegistrationId); + return; + } + + DCHECK(registration); + callback.Run(status, status_message, registration->id()); +} + void ServiceWorkerContextCore::UnregistrationComplete( const GURL& pattern, const ServiceWorkerContextCore::UnregistrationCallback& callback, diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h index ecffaca..4748aa9 100644 --- a/content/browser/service_worker/service_worker_context_core.h +++ b/content/browser/service_worker/service_worker_context_core.h @@ -58,6 +58,9 @@ class CONTENT_EXPORT ServiceWorkerContextCore typedef base::Callback<void(ServiceWorkerStatusCode status, const std::string& status_message, int64 registration_id)> RegistrationCallback; + typedef base::Callback<void(ServiceWorkerStatusCode status, + const std::string& status_message, + int64 registration_id)> UpdateCallback; typedef base::Callback< void(ServiceWorkerStatusCode status)> UnregistrationCallback; typedef IDMap<ServiceWorkerProviderHost, IDMapOwnPointer> ProviderMap; @@ -182,6 +185,10 @@ class CONTENT_EXPORT ServiceWorkerContextCore const UnregistrationCallback& callback); void UpdateServiceWorker(ServiceWorkerRegistration* registration, bool force_bypass_cache); + void UpdateServiceWorker(ServiceWorkerRegistration* registration, + bool force_bypass_cache, + ServiceWorkerProviderHost* provider_host, + const UpdateCallback& callback); // This class maintains collections of live instances, this class // does not own these object or influence their lifetime. @@ -245,6 +252,11 @@ class CONTENT_EXPORT ServiceWorkerContextCore const std::string& status_message, ServiceWorkerRegistration* registration); + void UpdateComplete(const UpdateCallback& callback, + ServiceWorkerStatusCode status, + const std::string& status_message, + ServiceWorkerRegistration* registration); + void UnregistrationComplete(const GURL& pattern, const UnregistrationCallback& callback, int64 registration_id, diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc index 1c443d3..f1ee3e7 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc @@ -41,6 +41,7 @@ const char kShutdownErrorMessage[] = "The Service Worker system has shutdown."; const char kUserDeniedPermissionMessage[] = "The user denied permission to use Service Worker."; +const char kInvalidStateErrorMessage[] = "The object is in an invalid state."; const uint32 kFilteredMessageClasses[] = { ServiceWorkerMsgStart, @@ -364,12 +365,19 @@ void ServiceWorkerDispatcherHost::OnRegisterServiceWorker( request_id)); } -void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int provider_id, +void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int thread_id, + int request_id, + int provider_id, int64 registration_id) { TRACE_EVENT0("ServiceWorker", "ServiceWorkerDispatcherHost::OnUpdateServiceWorker"); - if (!GetContext()) + if (!GetContext()) { + Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( + thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort, + base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + + base::ASCIIToUTF16(kShutdownErrorMessage))); return; + } ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(render_process_id_, provider_id); @@ -377,12 +385,22 @@ void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int provider_id, bad_message::ReceivedBadMessage(this, bad_message::SWDH_UPDATE_NO_HOST); return; } - if (!provider_host->IsContextAlive()) + if (!provider_host->IsContextAlive()) { + Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( + thread_id, request_id, WebServiceWorkerError::ErrorTypeAbort, + base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + + base::ASCIIToUTF16(kShutdownErrorMessage))); return; + } - // TODO(ksakamoto): This check can be removed once crbug.com/439697 is fixed. - if (provider_host->document_url().is_empty()) + // TODO(jungkees): This check can be removed once crbug.com/439697 is fixed. + if (provider_host->document_url().is_empty()) { + Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( + thread_id, request_id, WebServiceWorkerError::ErrorTypeSecurity, + base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + + base::ASCIIToUTF16(kNoDocumentURLErrorMessage))); return; + } ServiceWorkerRegistration* registration = GetContext()->GetLiveRegistration(registration_id); @@ -403,19 +421,29 @@ void ServiceWorkerDispatcherHost::OnUpdateServiceWorker(int provider_id, if (!GetContentClient()->browser()->AllowServiceWorker( registration->pattern(), provider_host->topmost_frame_url(), resource_context_, render_process_id_, provider_host->frame_id())) { + Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( + thread_id, request_id, WebServiceWorkerError::ErrorTypeUnknown, + base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + + base::ASCIIToUTF16(kUserDeniedPermissionMessage))); return; } if (!registration->GetNewestVersion()) { // This can happen if update() is called during initial script evaluation. // Abort the following steps according to the spec. + Send(new ServiceWorkerMsg_ServiceWorkerUpdateError( + thread_id, request_id, WebServiceWorkerError::ErrorTypeState, + base::ASCIIToUTF16(kServiceWorkerUpdateErrorPrefix) + + base::ASCIIToUTF16(kInvalidStateErrorMessage))); return; } // The spec says, "update() pings the server for an updated version of this // script without consulting caches", so set |force_bypass_cache| to true. - GetContext()->UpdateServiceWorker(registration, - true /* force_bypass_cache */); + GetContext()->UpdateServiceWorker( + registration, true, /* force_bypass_cache */ + provider_host, base::Bind(&ServiceWorkerDispatcherHost::UpdateComplete, + this, thread_id, provider_id, request_id)); } void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker( @@ -844,6 +872,41 @@ void ServiceWorkerDispatcherHost::RegistrationComplete( registration_id); } +void ServiceWorkerDispatcherHost::UpdateComplete( + int thread_id, + int provider_id, + int request_id, + ServiceWorkerStatusCode status, + const std::string& status_message, + int64 registration_id) { + if (!GetContext()) + return; + + ServiceWorkerProviderHost* provider_host = + GetContext()->GetProviderHost(render_process_id_, provider_id); + if (!provider_host) + return; // The provider has already been destroyed. + + if (status != SERVICE_WORKER_OK) { + SendRegistrationError(thread_id, request_id, status, status_message); + return; + } + + ServiceWorkerRegistration* registration = + GetContext()->GetLiveRegistration(registration_id); + DCHECK(registration); + + ServiceWorkerRegistrationObjectInfo info; + ServiceWorkerVersionAttributes attrs; + GetRegistrationObjectInfoAndVersionAttributes(provider_host->AsWeakPtr(), + registration, &info, &attrs); + + Send(new ServiceWorkerMsg_ServiceWorkerUpdated(thread_id, request_id)); + TRACE_EVENT_ASYNC_END1("ServiceWorker", + "ServiceWorkerDispatcherHost::UpdateServiceWorker", + request_id, "Registration ID", registration_id); +} + void ServiceWorkerDispatcherHost::OnWorkerReadyForInspection( int embedded_worker_id) { TRACE_EVENT0("ServiceWorker", diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h index c2e5c25..2635494 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.h +++ b/content/browser/service_worker/service_worker_dispatcher_host.h @@ -88,7 +88,10 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter { int provider_id, const GURL& pattern, const GURL& script_url); - void OnUpdateServiceWorker(int provider_id, int64 registration_id); + void OnUpdateServiceWorker(int thread_id, + int request_id, + int provider_id, + int64 registration_id); void OnUnregisterServiceWorker(int thread_id, int request_id, int provider_id, @@ -151,6 +154,13 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost : public BrowserMessageFilter { const std::string& status_message, int64 registration_id); + void UpdateComplete(int thread_id, + int provider_id, + int request_id, + ServiceWorkerStatusCode status, + const std::string& status_message, + int64 registration_id); + void UnregistrationComplete(int thread_id, int request_id, ServiceWorkerStatusCode status); diff --git a/content/browser/service_worker/service_worker_job_coordinator.cc b/content/browser/service_worker/service_worker_job_coordinator.cc index 71cc1e1..e2e73ff 100644 --- a/content/browser/service_worker/service_worker_job_coordinator.cc +++ b/content/browser/service_worker/service_worker_job_coordinator.cc @@ -133,6 +133,21 @@ void ServiceWorkerJobCoordinator::Update( force_bypass_cache))); } +void ServiceWorkerJobCoordinator::Update( + ServiceWorkerRegistration* registration, + bool force_bypass_cache, + ServiceWorkerProviderHost* provider_host, + const ServiceWorkerRegisterJob::RegistrationCallback& callback) { + DCHECK(registration); + DCHECK(registration->GetNewestVersion()); + ServiceWorkerRegisterJob* queued_job = static_cast<ServiceWorkerRegisterJob*>( + job_queues_[registration->pattern()].Push( + make_scoped_ptr<ServiceWorkerRegisterJobBase>( + new ServiceWorkerRegisterJob(context_, registration, + force_bypass_cache)))); + queued_job->AddCallback(callback, provider_host); +} + void ServiceWorkerJobCoordinator::AbortAll() { for (RegistrationJobMap::iterator it = job_queues_.begin(); it != job_queues_.end(); ++it) { diff --git a/content/browser/service_worker/service_worker_job_coordinator.h b/content/browser/service_worker/service_worker_job_coordinator.h index af1a8d8..f82a788 100644 --- a/content/browser/service_worker/service_worker_job_coordinator.h +++ b/content/browser/service_worker/service_worker_job_coordinator.h @@ -38,6 +38,11 @@ class CONTENT_EXPORT ServiceWorkerJobCoordinator { void Update(ServiceWorkerRegistration* registration, bool force_bypass_cache); + void Update(ServiceWorkerRegistration* registration, + bool force_bypass_cache, + ServiceWorkerProviderHost* provider_host, + const ServiceWorkerRegisterJob::RegistrationCallback& callback); + // Calls ServiceWorkerRegisterJobBase::Abort() on all jobs and removes them. void AbortAll(); |