| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/service_worker/service_worker_register_job.h" | 5 #include "content/browser/service_worker/service_worker_register_job.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "content/browser/service_worker/service_worker_context_core.h" | 10 #include "content/browser/service_worker/service_worker_context_core.h" |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 // "If serviceWorkerRegistration is null..." create a new registration. | 169 // "If serviceWorkerRegistration is null..." create a new registration. |
| 170 if (!existing_registration.get()) { | 170 if (!existing_registration.get()) { |
| 171 RegisterAndContinue(SERVICE_WORKER_OK); | 171 RegisterAndContinue(SERVICE_WORKER_OK); |
| 172 return; | 172 return; |
| 173 } | 173 } |
| 174 | 174 |
| 175 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to | 175 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to |
| 176 // script." We accomplish this by deleting the existing registration and | 176 // script." We accomplish this by deleting the existing registration and |
| 177 // registering a new one. | 177 // registering a new one. |
| 178 // TODO(falken): Match the spec. We now throw away the active_version_ and | 178 // TODO(falken): Match the spec. We now throw away the active_version_ and |
| 179 // pending_version_ of the existing registration, which isn't in the spec. | 179 // waiting_version_ of the existing registration, which isn't in the spec. |
| 180 // TODO(michaeln): Deactivate the live existing_registration object and | 180 // TODO(michaeln): Deactivate the live existing_registration object and |
| 181 // eventually call storage->DeleteVersionResources() | 181 // eventually call storage->DeleteVersionResources() |
| 182 // when it no longer has any controllees. | 182 // when it no longer has any controllees. |
| 183 context_->storage()->DeleteRegistration( | 183 context_->storage()->DeleteRegistration( |
| 184 existing_registration->id(), | 184 existing_registration->id(), |
| 185 existing_registration->script_url().GetOrigin(), | 185 existing_registration->script_url().GetOrigin(), |
| 186 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, | 186 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, |
| 187 weak_factory_.GetWeakPtr())); | 187 weak_factory_.GetWeakPtr())); |
| 188 } | 188 } |
| 189 | 189 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 207 // This function corresponds to the spec's _Update algorithm. | 207 // This function corresponds to the spec's _Update algorithm. |
| 208 void ServiceWorkerRegisterJob::UpdateAndContinue( | 208 void ServiceWorkerRegisterJob::UpdateAndContinue( |
| 209 ServiceWorkerStatusCode status) { | 209 ServiceWorkerStatusCode status) { |
| 210 SetPhase(UPDATE); | 210 SetPhase(UPDATE); |
| 211 if (status != SERVICE_WORKER_OK) { | 211 if (status != SERVICE_WORKER_OK) { |
| 212 // Abort this registration job. | 212 // Abort this registration job. |
| 213 Complete(status); | 213 Complete(status); |
| 214 return; | 214 return; |
| 215 } | 215 } |
| 216 | 216 |
| 217 // TODO(falken): "If serviceWorkerRegistration.pendingWorker is not null..." | 217 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." |
| 218 // then terminate the pending worker. It doesn't make sense to implement yet | 218 // then terminate the installing worker. It doesn't make sense to implement |
| 219 // since we always activate the worker if install completed, so there can be | 219 // yet since we always activate the worker if install completed, so there can |
| 220 // no pending worker at this point. | 220 // be no installing worker at this point. |
| 221 DCHECK(!registration()->pending_version()); | 221 // TODO(nhiroki): Check 'installing_version()' instead when it's supported. |
| 222 DCHECK(!registration()->waiting_version()); |
| 222 | 223 |
| 223 // "Let serviceWorker be a newly-created ServiceWorker object..." and start | 224 // "Let serviceWorker be a newly-created ServiceWorker object..." and start |
| 224 // the worker. | 225 // the worker. |
| 225 set_pending_version(new ServiceWorkerVersion( | 226 set_pending_version(new ServiceWorkerVersion( |
| 226 registration(), context_->storage()->NewVersionId(), context_)); | 227 registration(), context_->storage()->NewVersionId(), context_)); |
| 227 | 228 |
| 228 // TODO(michaeln): Start the worker into a paused state where the | 229 // TODO(michaeln): Start the worker into a paused state where the |
| 229 // script resource is downloaded but not yet evaluated. | 230 // script resource is downloaded but not yet evaluated. |
| 230 pending_version()->StartWorkerWithCandidateProcesses( | 231 pending_version()->StartWorkerWithCandidateProcesses( |
| 231 pending_process_ids_, | 232 pending_process_ids_, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 242 return; | 243 return; |
| 243 } | 244 } |
| 244 | 245 |
| 245 // TODO(michaeln): Compare the old and new script. | 246 // TODO(michaeln): Compare the old and new script. |
| 246 // If different unpause the worker and continue with | 247 // If different unpause the worker and continue with |
| 247 // the job. If the same ResolvePromise with the current | 248 // the job. If the same ResolvePromise with the current |
| 248 // version and complete the job, throwing away the new version | 249 // version and complete the job, throwing away the new version |
| 249 // since there's nothing new. | 250 // since there's nothing new. |
| 250 | 251 |
| 251 // "Resolve promise with serviceWorker." | 252 // "Resolve promise with serviceWorker." |
| 252 // Although the spec doesn't set pendingWorker until after resolving the | 253 // Although the spec doesn't set waitingWorker until after resolving the |
| 253 // promise, our system's resolving works by passing ServiceWorkerRegistration | 254 // promise, our system's resolving works by passing ServiceWorkerRegistration |
| 254 // to the callbacks, so pendingWorker must be set first. | 255 // to the callbacks, so waitingWorker must be set first. |
| 255 DCHECK(!registration()->pending_version()); | 256 DCHECK(!registration()->waiting_version()); |
| 256 registration()->set_pending_version(pending_version()); | 257 registration()->set_waiting_version(pending_version()); |
| 257 ResolvePromise(status, registration(), pending_version()); | 258 ResolvePromise(status, registration(), pending_version()); |
| 258 | 259 |
| 259 AssociatePendingVersionToDocuments(context_, pending_version()); | 260 AssociateWaitingVersionToDocuments(context_, pending_version()); |
| 260 | 261 |
| 261 InstallAndContinue(); | 262 InstallAndContinue(); |
| 262 } | 263 } |
| 263 | 264 |
| 264 // This function corresponds to the spec's _Install algorithm. | 265 // This function corresponds to the spec's _Install algorithm. |
| 265 void ServiceWorkerRegisterJob::InstallAndContinue() { | 266 void ServiceWorkerRegisterJob::InstallAndContinue() { |
| 266 SetPhase(INSTALL); | 267 SetPhase(INSTALL); |
| 267 // "Set serviceWorkerRegistration.pendingWorker._state to installing." | 268 // "Set serviceWorkerRegistration.installingWorker._state to installing." |
| 268 // "Fire install event on the associated ServiceWorkerGlobalScope object." | 269 // "Fire install event on the associated ServiceWorkerGlobalScope object." |
| 269 pending_version()->DispatchInstallEvent( | 270 pending_version()->DispatchInstallEvent( |
| 270 -1, | 271 -1, |
| 271 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, | 272 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, |
| 272 weak_factory_.GetWeakPtr())); | 273 weak_factory_.GetWeakPtr())); |
| 273 } | 274 } |
| 274 | 275 |
| 275 void ServiceWorkerRegisterJob::OnInstallFinished( | 276 void ServiceWorkerRegisterJob::OnInstallFinished( |
| 276 ServiceWorkerStatusCode status) { | 277 ServiceWorkerStatusCode status) { |
| 277 // "If any handler called waitUntil()..." and the resulting promise | 278 // "If any handler called waitUntil()..." and the resulting promise |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 // registration already has an active version, so we shouldn't come | 317 // registration already has an active version, so we shouldn't come |
| 317 // this way. | 318 // this way. |
| 318 NOTREACHED(); | 319 NOTREACHED(); |
| 319 // TODO(falken): Register an continuation task to wait for NoControllees | 320 // TODO(falken): Register an continuation task to wait for NoControllees |
| 320 // notification so that we can resume activation later (see comments | 321 // notification so that we can resume activation later (see comments |
| 321 // in ServiceWorkerVersion::RemoveControllee). | 322 // in ServiceWorkerVersion::RemoveControllee). |
| 322 Complete(SERVICE_WORKER_OK); | 323 Complete(SERVICE_WORKER_OK); |
| 323 return; | 324 return; |
| 324 } | 325 } |
| 325 | 326 |
| 326 // "Set serviceWorkerRegistration.pendingWorker to null." | 327 // "Set serviceWorkerRegistration.waitingWorker to null." |
| 327 // "Set serviceWorkerRegistration.activeWorker to activatingWorker." | 328 // "Set serviceWorkerRegistration.activeWorker to activatingWorker." |
| 328 DisassociatePendingVersionFromDocuments( | 329 DisassociateWaitingVersionFromDocuments( |
| 329 context_, pending_version()->version_id()); | 330 context_, pending_version()->version_id()); |
| 330 registration()->set_pending_version(NULL); | 331 registration()->set_waiting_version(NULL); |
| 331 DCHECK(!registration()->active_version()); | 332 DCHECK(!registration()->active_version()); |
| 332 registration()->set_active_version(pending_version()); | 333 registration()->set_active_version(pending_version()); |
| 333 | 334 |
| 334 // "Set serviceWorkerRegistration.activeWorker._state to activating." | 335 // "Set serviceWorkerRegistration.activeWorker._state to activating." |
| 335 // "Fire activate event on the associated ServiceWorkerGlobalScope object." | 336 // "Fire activate event on the associated ServiceWorkerGlobalScope object." |
| 336 // "Set serviceWorkerRegistration.activeWorker._state to active." | 337 // "Set serviceWorkerRegistration.activeWorker._state to active." |
| 337 pending_version()->DispatchActivateEvent( | 338 pending_version()->DispatchActivateEvent( |
| 338 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, | 339 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, |
| 339 weak_factory_.GetWeakPtr())); | 340 weak_factory_.GetWeakPtr())); |
| 340 } | 341 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 352 } | 353 } |
| 353 context_->storage()->UpdateToActiveState( | 354 context_->storage()->UpdateToActiveState( |
| 354 registration(), | 355 registration(), |
| 355 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 356 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
| 356 Complete(SERVICE_WORKER_OK); | 357 Complete(SERVICE_WORKER_OK); |
| 357 } | 358 } |
| 358 | 359 |
| 359 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { | 360 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { |
| 360 SetPhase(COMPLETE); | 361 SetPhase(COMPLETE); |
| 361 if (status != SERVICE_WORKER_OK) { | 362 if (status != SERVICE_WORKER_OK) { |
| 362 if (registration() && registration()->pending_version()) { | 363 if (registration() && registration()->waiting_version()) { |
| 363 DisassociatePendingVersionFromDocuments( | 364 DisassociateWaitingVersionFromDocuments( |
| 364 context_, registration()->pending_version()->version_id()); | 365 context_, registration()->waiting_version()->version_id()); |
| 365 registration()->set_pending_version(NULL); | 366 registration()->set_waiting_version(NULL); |
| 366 } | 367 } |
| 367 if (registration() && !registration()->active_version()) { | 368 if (registration() && !registration()->active_version()) { |
| 368 context_->storage()->DeleteRegistration( | 369 context_->storage()->DeleteRegistration( |
| 369 registration()->id(), | 370 registration()->id(), |
| 370 registration()->script_url().GetOrigin(), | 371 registration()->script_url().GetOrigin(), |
| 371 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 372 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
| 372 } | 373 } |
| 373 if (!is_promise_resolved_) | 374 if (!is_promise_resolved_) |
| 374 ResolvePromise(status, NULL, NULL); | 375 ResolvePromise(status, NULL, NULL); |
| 375 } | 376 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 392 promise_resolved_version_ = version; | 393 promise_resolved_version_ = version; |
| 393 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); | 394 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); |
| 394 it != callbacks_.end(); | 395 it != callbacks_.end(); |
| 395 ++it) { | 396 ++it) { |
| 396 it->Run(status, registration, version); | 397 it->Run(status, registration, version); |
| 397 } | 398 } |
| 398 callbacks_.clear(); | 399 callbacks_.clear(); |
| 399 } | 400 } |
| 400 | 401 |
| 401 // static | 402 // static |
| 402 void ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments( | 403 void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments( |
| 403 base::WeakPtr<ServiceWorkerContextCore> context, | 404 base::WeakPtr<ServiceWorkerContextCore> context, |
| 404 ServiceWorkerVersion* version) { | 405 ServiceWorkerVersion* version) { |
| 405 DCHECK(context); | 406 DCHECK(context); |
| 406 DCHECK(version); | 407 DCHECK(version); |
| 407 | 408 |
| 408 // TODO(michaeln): This needs to respect the longest prefix wins | 409 // TODO(michaeln): This needs to respect the longest prefix wins |
| 409 // when it comes to finding a registration for a document url. | 410 // when it comes to finding a registration for a document url. |
| 410 // This should utilize storage->FindRegistrationForDocument(). | 411 // This should utilize storage->FindRegistrationForDocument(). |
| 411 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 412 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
| 412 context->GetProviderHostIterator(); | 413 context->GetProviderHostIterator(); |
| 413 !it->IsAtEnd(); | 414 !it->IsAtEnd(); |
| 414 it->Advance()) { | 415 it->Advance()) { |
| 415 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 416 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
| 416 if (ServiceWorkerUtils::ScopeMatches(version->scope(), | 417 if (ServiceWorkerUtils::ScopeMatches(version->scope(), |
| 417 host->document_url())) | 418 host->document_url())) |
| 418 host->SetPendingVersion(version); | 419 host->SetWaitingVersion(version); |
| 420 // TODO(nhiroki): Take care of 'installing' version when it's supported. |
| 419 } | 421 } |
| 420 } | 422 } |
| 421 | 423 |
| 422 // static | 424 // static |
| 423 void ServiceWorkerRegisterJob::DisassociatePendingVersionFromDocuments( | 425 void ServiceWorkerRegisterJob::DisassociateWaitingVersionFromDocuments( |
| 424 base::WeakPtr<ServiceWorkerContextCore> context, | 426 base::WeakPtr<ServiceWorkerContextCore> context, |
| 425 int64 version_id) { | 427 int64 version_id) { |
| 426 DCHECK(context); | 428 DCHECK(context); |
| 427 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 429 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
| 428 context->GetProviderHostIterator(); | 430 context->GetProviderHostIterator(); |
| 429 !it->IsAtEnd(); | 431 !it->IsAtEnd(); |
| 430 it->Advance()) { | 432 it->Advance()) { |
| 431 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 433 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
| 432 if (host->pending_version() && | 434 if (host->waiting_version() && |
| 433 host->pending_version()->version_id() == version_id) { | 435 host->waiting_version()->version_id() == version_id) { |
| 434 host->SetPendingVersion(NULL); | 436 host->SetWaitingVersion(NULL); |
| 435 } | 437 } |
| 436 } | 438 } |
| 437 } | 439 } |
| 438 | 440 |
| 439 } // namespace content | 441 } // namespace content |
| OLD | NEW |