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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
176 Complete(status); | 176 Complete(status); |
177 return; | 177 return; |
178 } | 178 } |
179 | 179 |
180 // "If serviceWorkerRegistration is not null and script is equal to | 180 // "If serviceWorkerRegistration is not null and script is equal to |
181 // serviceWorkerRegistration.scriptUrl..." resolve with the existing | 181 // serviceWorkerRegistration.scriptUrl..." resolve with the existing |
182 // registration and abort. | 182 // registration and abort. |
183 if (existing_registration.get() && | 183 if (existing_registration.get() && |
184 existing_registration->script_url() == script_url_) { | 184 existing_registration->script_url() == script_url_) { |
185 set_registration(existing_registration); | 185 set_registration(existing_registration); |
186 AssociateProviderHostToRegistration(existing_registration); | |
186 // If there's no active version, go ahead to Update (this isn't in the spec | 187 // If there's no active version, go ahead to Update (this isn't in the spec |
187 // but seems reasonable, and without SoftUpdate implemented we can never | 188 // but seems reasonable, and without SoftUpdate implemented we can never |
188 // Update otherwise). | 189 // Update otherwise). |
189 if (!existing_registration->active_version()) { | 190 if (!existing_registration->active_version()) { |
190 UpdateAndContinue(); | 191 UpdateAndContinue(); |
191 return; | 192 return; |
192 } | 193 } |
193 ResolvePromise( | 194 ResolvePromise( |
194 status, existing_registration, existing_registration->active_version()); | 195 status, existing_registration, existing_registration->active_version()); |
195 Complete(SERVICE_WORKER_OK); | 196 Complete(SERVICE_WORKER_OK); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 SetPhase(REGISTER); | 241 SetPhase(REGISTER); |
241 if (status != SERVICE_WORKER_OK) { | 242 if (status != SERVICE_WORKER_OK) { |
242 // Abort this registration job. | 243 // Abort this registration job. |
243 Complete(status); | 244 Complete(status); |
244 return; | 245 return; |
245 } | 246 } |
246 | 247 |
247 set_registration(new ServiceWorkerRegistration( | 248 set_registration(new ServiceWorkerRegistration( |
248 pattern_, script_url_, context_->storage()->NewRegistrationId(), | 249 pattern_, script_url_, context_->storage()->NewRegistrationId(), |
249 context_)); | 250 context_)); |
251 AssociateProviderHostToRegistration(registration()); | |
250 UpdateAndContinue(); | 252 UpdateAndContinue(); |
251 } | 253 } |
252 | 254 |
253 // This function corresponds to the spec's [[Update]] algorithm. | 255 // This function corresponds to the spec's [[Update]] algorithm. |
254 void ServiceWorkerRegisterJob::UpdateAndContinue() { | 256 void ServiceWorkerRegisterJob::UpdateAndContinue() { |
255 SetPhase(UPDATE); | 257 SetPhase(UPDATE); |
256 context_->storage()->NotifyInstallingRegistration(registration()); | 258 context_->storage()->NotifyInstallingRegistration(registration()); |
257 | 259 |
258 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." | 260 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." |
259 // then terminate the installing worker. It doesn't make sense to implement | 261 // then terminate the installing worker. It doesn't make sense to implement |
(...skipping 29 matching lines...) Expand all Loading... | |
289 ResolvePromise(status, registration(), new_version()); | 291 ResolvePromise(status, registration(), new_version()); |
290 InstallAndContinue(); | 292 InstallAndContinue(); |
291 } | 293 } |
292 | 294 |
293 // This function corresponds to the spec's _Install algorithm. | 295 // This function corresponds to the spec's _Install algorithm. |
294 void ServiceWorkerRegisterJob::InstallAndContinue() { | 296 void ServiceWorkerRegisterJob::InstallAndContinue() { |
295 SetPhase(INSTALL); | 297 SetPhase(INSTALL); |
296 | 298 |
297 // "3. Set registration.installingWorker to worker." | 299 // "3. Set registration.installingWorker to worker." |
298 registration()->SetInstallingVersion(new_version()); | 300 registration()->SetInstallingVersion(new_version()); |
299 AssociateInstallingVersionToDocuments(context_, new_version()); | |
300 | 301 |
301 // "4. Run the [[UpdateState]] algorithm passing registration.installingWorker | 302 // "4. Run the [[UpdateState]] algorithm passing registration.installingWorker |
302 // and "installing" as the arguments." | 303 // and "installing" as the arguments." |
303 new_version()->SetStatus(ServiceWorkerVersion::INSTALLING); | 304 new_version()->SetStatus(ServiceWorkerVersion::INSTALLING); |
304 | 305 |
305 // TODO(nhiroki,michaeln): "5. Fire a simple event named updatefound..." | 306 // TODO(nhiroki,michaeln): "5. Fire a simple event named updatefound..." |
306 | 307 |
307 // "6. Fire an event named install..." | 308 // "6. Fire an event named install..." |
308 new_version()->DispatchInstallEvent( | 309 new_version()->DispatchInstallEvent( |
309 -1, | 310 -1, |
(...skipping 29 matching lines...) Expand all Loading... | |
339 // "9. If registration.waitingWorker is not null, then:..." | 340 // "9. If registration.waitingWorker is not null, then:..." |
340 if (registration()->waiting_version()) { | 341 if (registration()->waiting_version()) { |
341 // "1. Run the [[UpdateState]] algorithm passing registration.waitingWorker | 342 // "1. Run the [[UpdateState]] algorithm passing registration.waitingWorker |
342 // and "redundant" as the arguments." | 343 // and "redundant" as the arguments." |
343 registration()->waiting_version()->SetStatus( | 344 registration()->waiting_version()->SetStatus( |
344 ServiceWorkerVersion::REDUNDANT); | 345 ServiceWorkerVersion::REDUNDANT); |
345 } | 346 } |
346 | 347 |
347 // "10. Set registration.waitingWorker to registration.installingWorker." | 348 // "10. Set registration.waitingWorker to registration.installingWorker." |
348 // "11. Set registration.installingWorker to null." | 349 // "11. Set registration.installingWorker to null." |
349 DisassociateVersionFromDocuments(context_, new_version()); | |
350 registration()->SetWaitingVersion(new_version()); | 350 registration()->SetWaitingVersion(new_version()); |
351 AssociateWaitingVersionToDocuments(context_, new_version()); | |
352 | 351 |
353 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker | 352 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker |
354 // and "installed" as the arguments." | 353 // and "installed" as the arguments." |
355 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED); | 354 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED); |
356 | 355 |
357 // TODO(michaeln): "13. If activateImmediate is true, then..." | 356 // TODO(michaeln): "13. If activateImmediate is true, then..." |
358 | 357 |
359 // "14. Wait until no document is using registration as their | 358 // "14. Wait until no document is using registration as their |
360 // Service Worker registration." | 359 // Service Worker registration." |
361 registration()->ActivateWaitingVersionWhenReady(); | 360 registration()->ActivateWaitingVersionWhenReady(); |
362 | 361 |
363 Complete(SERVICE_WORKER_OK); | 362 Complete(SERVICE_WORKER_OK); |
364 } | 363 } |
365 | 364 |
366 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { | 365 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { |
367 CompleteInternal(status); | 366 CompleteInternal(status); |
368 context_->job_coordinator()->FinishJob(pattern_, this); | 367 context_->job_coordinator()->FinishJob(pattern_, this); |
369 } | 368 } |
370 | 369 |
371 void ServiceWorkerRegisterJob::CompleteInternal( | 370 void ServiceWorkerRegisterJob::CompleteInternal( |
372 ServiceWorkerStatusCode status) { | 371 ServiceWorkerStatusCode status) { |
373 SetPhase(COMPLETE); | 372 SetPhase(COMPLETE); |
374 if (status != SERVICE_WORKER_OK) { | 373 if (status != SERVICE_WORKER_OK) { |
375 if (registration()) { | 374 if (registration()) { |
376 if (new_version()) { | 375 if (new_version()) { |
377 DisassociateVersionFromDocuments(context_, new_version()); | |
378 registration()->UnsetVersion(new_version()); | 376 registration()->UnsetVersion(new_version()); |
379 new_version()->Doom(); | 377 new_version()->Doom(); |
380 } | 378 } |
381 if (!registration()->active_version()) { | 379 if (!registration()->active_version()) { |
382 context_->storage()->DeleteRegistration( | 380 context_->storage()->DeleteRegistration( |
383 registration()->id(), | 381 registration()->id(), |
384 registration()->script_url().GetOrigin(), | 382 registration()->script_url().GetOrigin(), |
385 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 383 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
386 } | 384 } |
387 } | 385 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
446 ResolvePromise(SERVICE_WORKER_OK, registration(), current_version); | 444 ResolvePromise(SERVICE_WORKER_OK, registration(), current_version); |
447 Complete(SERVICE_WORKER_ERROR_EXISTS); | 445 Complete(SERVICE_WORKER_ERROR_EXISTS); |
448 return; | 446 return; |
449 } | 447 } |
450 | 448 |
451 // Proceed with really starting the worker. | 449 // Proceed with really starting the worker. |
452 new_version()->embedded_worker()->ResumeAfterDownload(); | 450 new_version()->embedded_worker()->ResumeAfterDownload(); |
453 new_version()->embedded_worker()->RemoveListener(this); | 451 new_version()->embedded_worker()->RemoveListener(this); |
454 } | 452 } |
455 | 453 |
456 // static | 454 void ServiceWorkerRegisterJob::AssociateProviderHostToRegistration( |
457 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments( | 455 ServiceWorkerRegistration* registration) { |
458 base::WeakPtr<ServiceWorkerContextCore> context, | 456 DCHECK(registration); |
459 ServiceWorkerVersion* version) { | |
460 DCHECK(context); | |
461 DCHECK(version); | |
462 | |
463 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 457 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
464 context->GetProviderHostIterator(); | 458 context_->GetProviderHostIterator(); |
465 !it->IsAtEnd(); it->Advance()) { | 459 !it->IsAtEnd(); it->Advance()) { |
466 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 460 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
467 if (ServiceWorkerUtils::ScopeMatches(version->scope(), | 461 if (ServiceWorkerUtils::ScopeMatches(registration->pattern(), |
468 host->document_url())) { | 462 host->document_url())) { |
469 if (!host->CanAssociateVersion(version)) | 463 host->AssociateRegistration(registration); |
falken
2014/08/05 02:41:28
I wonder what happens in cases like register(), lo
nhiroki
2014/08/05 15:51:13
Thank you for sharing the issue. Yes, this is alre
| |
470 continue; | |
471 host->SetInstallingVersion(version); | |
472 } | 464 } |
473 } | 465 } |
474 } | 466 } |
475 | 467 |
476 // static | |
477 void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments( | |
478 base::WeakPtr<ServiceWorkerContextCore> context, | |
479 ServiceWorkerVersion* version) { | |
480 DCHECK(context); | |
481 DCHECK(version); | |
482 | |
483 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | |
484 context->GetProviderHostIterator(); | |
485 !it->IsAtEnd(); it->Advance()) { | |
486 ServiceWorkerProviderHost* host = it->GetProviderHost(); | |
487 if (ServiceWorkerUtils::ScopeMatches(version->scope(), | |
488 host->document_url())) { | |
489 if (!host->CanAssociateVersion(version)) | |
490 continue; | |
491 host->SetWaitingVersion(version); | |
492 } | |
493 } | |
494 } | |
495 | |
496 // static | |
497 void ServiceWorkerRegisterJob::AssociateActiveVersionToDocuments( | |
498 base::WeakPtr<ServiceWorkerContextCore> context, | |
499 ServiceWorkerVersion* version) { | |
500 DCHECK(context); | |
501 DCHECK(version); | |
502 | |
503 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | |
504 context->GetProviderHostIterator(); | |
505 !it->IsAtEnd(); it->Advance()) { | |
506 ServiceWorkerProviderHost* host = it->GetProviderHost(); | |
507 if (ServiceWorkerUtils::ScopeMatches(version->scope(), | |
508 host->document_url())) { | |
509 if (!host->CanAssociateVersion(version)) | |
510 continue; | |
511 host->SetActiveVersion(version); | |
512 } | |
513 } | |
514 } | |
515 | |
516 // static | |
517 void ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( | |
518 base::WeakPtr<ServiceWorkerContextCore> context, | |
519 ServiceWorkerVersion* version) { | |
520 DCHECK(context); | |
521 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | |
522 context->GetProviderHostIterator(); | |
523 !it->IsAtEnd(); it->Advance()) { | |
524 ServiceWorkerProviderHost* host = it->GetProviderHost(); | |
525 host->UnsetVersion(version); | |
526 } | |
527 } | |
528 | |
529 } // namespace content | 468 } // namespace content |
OLD | NEW |