Chromium Code Reviews| 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 a0453313bc0d33e636ac973cd616178b878e28a5..f5826a47095488de61e8878e3a35e7086ffc8e2b 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; | 
| } | 
| +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,36 +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->script_url() == script_url_) { | 
| - // Spec says to resolve with registration.[[GetNewestWorker]]. We come close | 
| - // by resolving with the active version. | 
| - set_registration(existing_registration); | 
| - | 
| - 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, 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->script_url().GetOrigin(), | 
| - base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, | 
| - weak_factory_.GetWeakPtr())); | 
| + // "Set registration.[[ScriptURL]] to scriptURL." | 
| + existing_registration->set_script_url(script_url_); | 
| + | 
| 
 
nhiroki
2014/08/21 01:57:17
Just an idea: To explicitly ensure the step "5. Se
 
falken
2014/08/21 02:40:38
Sounds good. Done.
 
 | 
| + // "Return the result of running the [[Update]] algorithm, or its equivalent, | 
| + // passing registration as the argument." | 
| + set_registration(existing_registration); | 
| + UpdateAndContinue(); | 
| } | 
| void ServiceWorkerRegisterJob::ContinueWithUpdate( | 
| @@ -256,6 +266,34 @@ 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 steps. Resolve if the newest version | 
| + // shares the script URL. | 
| + 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); | 
| @@ -445,6 +483,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, |