Index: content/browser/service_worker/service_worker_register_job.cc |
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc |
index 81582d965f365d8366f2a5eeca865b094bf610e6..2276cf87089ee5a4bf10e858f0ae89754e971166 100644 |
--- a/content/browser/service_worker/service_worker_register_job.cc |
+++ b/content/browser/service_worker/service_worker_register_job.cc |
@@ -140,6 +140,18 @@ ServiceWorkerVersion* ServiceWorkerRegisterJob::new_version() { |
return internal_.new_version.get(); |
} |
+void ServiceWorkerRegisterJob::set_uninstalling_registration( |
+ ServiceWorkerRegistration* registration) { |
+ DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL); |
+ internal_.uninstalling_registration = registration; |
+} |
+ |
+ServiceWorkerRegistration* |
+ServiceWorkerRegisterJob::uninstalling_registration() { |
+ DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL); |
+ return internal_.uninstalling_registration; |
+} |
+ |
void ServiceWorkerRegisterJob::SetPhase(Phase phase) { |
switch (phase) { |
case INITIAL: |
@@ -148,9 +160,12 @@ void ServiceWorkerRegisterJob::SetPhase(Phase phase) { |
case START: |
DCHECK(phase_ == INITIAL) << phase_; |
break; |
- case REGISTER: |
+ case WAIT_FOR_UNINSTALL: |
DCHECK(phase_ == START) << phase_; |
break; |
+ case REGISTER: |
+ DCHECK(phase_ == START || phase_ == WAIT_FOR_UNINSTALL) << phase_; |
+ break; |
case UPDATE: |
DCHECK(phase_ == START || phase_ == REGISTER) << phase_; |
break; |
@@ -186,37 +201,31 @@ void ServiceWorkerRegisterJob::ContinueWithRegistration( |
return; |
} |
- // "Set registration.[[Uninstalling]] to false." |
- existing_registration->AbortPendingClear(); |
- |
// "If scriptURL is equal to registration.[[ScriptURL]], then:" |
if (existing_registration->GetNewestVersion()->script_url() == script_url_) { |
- // Spec says to resolve with registration.[[GetNewestWorker]]. We come close |
- // by resolving with the active version. |
- set_registration(existing_registration.get()); |
- |
- if (!existing_registration->active_version()) { |
- UpdateAndContinue(); |
- return; |
- } |
+ // "Set registration.[[Uninstalling]] to false." |
+ existing_registration->AbortPendingClear(base::Bind( |
+ &ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl, |
+ weak_factory_.GetWeakPtr(), |
+ existing_registration)); |
+ return; |
+ } |
- ResolvePromise(status, |
- existing_registration.get(), |
- existing_registration->active_version()); |
- Complete(SERVICE_WORKER_OK); |
+ if (existing_registration->is_uninstalling()) { |
+ // "Wait until the Record {[[key]], [[value]]} entry of its |
+ // [[ScopeToRegistrationMap]] where registation.scope matches entry.[[key]] |
+ // is deleted." |
+ WaitForUninstall(existing_registration); |
return; |
} |
- // "Set registration.[[ScriptURL]] to scriptURL." We accomplish this by |
- // deleting the existing registration and registering a new one. |
- // TODO(michaeln): Deactivate the live existing_registration object and |
- // eventually call storage->DeleteVersionResources() when it no longer has any |
- // controllees. |
- context_->storage()->DeleteRegistration( |
- existing_registration->id(), |
- existing_registration->pattern().GetOrigin(), |
- base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, |
- weak_factory_.GetWeakPtr())); |
+ // "Set registration.[[Uninstalling]] to false." |
+ DCHECK(!existing_registration->is_uninstalling()); |
+ |
+ // "Return the result of running the [[Update]] algorithm, or its equivalent, |
+ // passing registration as the argument." |
+ set_registration(existing_registration); |
+ UpdateAndContinue(); |
} |
void ServiceWorkerRegisterJob::ContinueWithUpdate( |
@@ -264,6 +273,35 @@ void ServiceWorkerRegisterJob::RegisterAndContinue( |
UpdateAndContinue(); |
} |
+void ServiceWorkerRegisterJob::WaitForUninstall( |
+ const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { |
+ SetPhase(WAIT_FOR_UNINSTALL); |
+ set_uninstalling_registration(existing_registration); |
+ uninstalling_registration()->AddListener(this); |
+} |
+ |
+void ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl( |
+ const scoped_refptr<ServiceWorkerRegistration>& existing_registration, |
+ ServiceWorkerStatusCode status) { |
+ if (status != SERVICE_WORKER_OK) { |
+ Complete(status); |
+ return; |
+ } |
+ set_registration(existing_registration); |
+ |
+ // TODO(falken): Follow the spec: resolve the promise |
+ // with the newest version. |
+ |
+ if (!existing_registration->active_version()) { |
+ UpdateAndContinue(); |
+ return; |
+ } |
+ |
+ ResolvePromise( |
+ status, existing_registration, existing_registration->active_version()); |
+ Complete(SERVICE_WORKER_OK); |
+} |
+ |
// This function corresponds to the spec's [[Update]] algorithm. |
void ServiceWorkerRegisterJob::UpdateAndContinue() { |
SetPhase(UPDATE); |
@@ -455,6 +493,15 @@ bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { |
return false; |
} |
+void ServiceWorkerRegisterJob::OnRegistrationFinishedUninstalling( |
+ ServiceWorkerRegistration* existing_registration) { |
+ DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL); |
+ DCHECK_EQ(existing_registration, uninstalling_registration()); |
+ existing_registration->RemoveListener(this); |
+ set_uninstalling_registration(NULL); |
+ RegisterAndContinue(SERVICE_WORKER_OK); |
+} |
+ |
void ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete( |
ServiceWorkerVersion* most_recent_version, |
ServiceWorkerStatusCode status, |