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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 if (status != SERVICE_WORKER_OK) { | 222 if (status != SERVICE_WORKER_OK) { |
223 // Abort this registration job. | 223 // Abort this registration job. |
224 Complete(status); | 224 Complete(status); |
225 return; | 225 return; |
226 } | 226 } |
227 | 227 |
228 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." | 228 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." |
229 // then terminate the installing worker. It doesn't make sense to implement | 229 // then terminate the installing worker. It doesn't make sense to implement |
230 // yet since we always activate the worker if install completed, so there can | 230 // yet since we always activate the worker if install completed, so there can |
231 // be no installing worker at this point. | 231 // be no installing worker at this point. |
232 // TODO(nhiroki): Check 'installing_version()' instead when it's supported. | |
233 | 232 |
234 // "Let serviceWorker be a newly-created ServiceWorker object..." and start | 233 // "Let serviceWorker be a newly-created ServiceWorker object..." and start |
235 // the worker. | 234 // the worker. |
236 set_new_version(new ServiceWorkerVersion( | 235 set_new_version(new ServiceWorkerVersion( |
237 registration(), context_->storage()->NewVersionId(), context_)); | 236 registration(), context_->storage()->NewVersionId(), context_)); |
238 | 237 |
239 // TODO(michaeln): Pause after downloading when performing an update. | 238 // TODO(michaeln): Pause after downloading when performing an update. |
240 bool pause_after_download = false; | 239 bool pause_after_download = false; |
241 if (pause_after_download) | 240 if (pause_after_download) |
242 new_version()->embedded_worker()->AddListener(this); | 241 new_version()->embedded_worker()->AddListener(this); |
243 new_version()->StartWorkerWithCandidateProcesses( | 242 new_version()->StartWorkerWithCandidateProcesses( |
244 pending_process_ids_, | 243 pending_process_ids_, |
245 pause_after_download, | 244 pause_after_download, |
246 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, | 245 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, |
247 weak_factory_.GetWeakPtr())); | 246 weak_factory_.GetWeakPtr())); |
248 } | 247 } |
249 | 248 |
250 void ServiceWorkerRegisterJob::OnStartWorkerFinished( | 249 void ServiceWorkerRegisterJob::OnStartWorkerFinished( |
251 ServiceWorkerStatusCode status) { | 250 ServiceWorkerStatusCode status) { |
252 // "If serviceWorker fails to start up..." then reject the promise with an | 251 // "If serviceWorker fails to start up..." then reject the promise with an |
253 // error and abort. | 252 // error and abort. |
254 if (status != SERVICE_WORKER_OK) { | 253 if (status != SERVICE_WORKER_OK) { |
255 Complete(status); | 254 Complete(status); |
256 return; | 255 return; |
257 } | 256 } |
258 | 257 |
259 // "Resolve promise with serviceWorker." | 258 // "Resolve promise with serviceWorker." |
260 DCHECK(!registration()->installing_version()); | 259 DCHECK(!registration()->installing_version()); |
261 ResolvePromise(status, registration(), new_version()); | 260 ResolvePromise(status, registration(), new_version()); |
262 registration()->SetInstallingVersion(new_version()); | |
263 AssociateInstallingVersionToDocuments(context_, new_version()); | |
264 InstallAndContinue(); | 261 InstallAndContinue(); |
265 } | 262 } |
266 | 263 |
267 // This function corresponds to the spec's _Install algorithm. | 264 // This function corresponds to the spec's _Install algorithm. |
268 void ServiceWorkerRegisterJob::InstallAndContinue() { | 265 void ServiceWorkerRegisterJob::InstallAndContinue() { |
269 SetPhase(INSTALL); | 266 SetPhase(INSTALL); |
270 // "Set serviceWorkerRegistration.installingWorker._state to installing." | 267 |
271 // "Fire install event on the associated ServiceWorkerGlobalScope object." | 268 // "3. Set registration.installingWorker to worker." |
269 registration()->SetInstallingVersion(new_version()); | |
270 AssociateInstallingVersionToDocuments(context_, new_version()); | |
271 | |
272 // "4. Run the [[UpdateState]] algorithm passing registration.installingWorker | |
273 // and "installing" as the arguments." | |
274 new_version()->SetStatus(ServiceWorkerVersion::INSTALLING); | |
275 | |
276 // TODO(nhiroki,michaeln): "5. Fire a simple event named updatefound..." | |
277 | |
278 // "6. Fire an event named install..." | |
272 new_version()->DispatchInstallEvent( | 279 new_version()->DispatchInstallEvent( |
273 -1, | 280 -1, |
274 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, | 281 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, |
275 weak_factory_.GetWeakPtr())); | 282 weak_factory_.GetWeakPtr())); |
276 } | 283 } |
277 | 284 |
278 void ServiceWorkerRegisterJob::OnInstallFinished( | 285 void ServiceWorkerRegisterJob::OnInstallFinished( |
279 ServiceWorkerStatusCode status) { | 286 ServiceWorkerStatusCode status) { |
280 // "If any handler called waitUntil()..." and the resulting promise | |
281 // is rejected, abort. | |
282 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is | 287 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is |
283 // unexpectedly terminated) we may want to retry sending the event again. | 288 // unexpectedly terminated) we may want to retry sending the event again. |
284 if (status != SERVICE_WORKER_OK) { | 289 if (status != SERVICE_WORKER_OK) { |
290 // "8. If installFailed is true, then:..." | |
291 new_version()->SetStatus(ServiceWorkerVersion::REDUNDANT); | |
292 registration()->SetInstallingVersion(NULL); | |
285 Complete(status); | 293 Complete(status); |
286 return; | 294 return; |
287 } | 295 } |
288 | 296 |
289 SetPhase(STORE); | 297 SetPhase(STORE); |
290 context_->storage()->StoreRegistration( | 298 context_->storage()->StoreRegistration( |
291 registration(), | 299 registration(), |
292 new_version(), | 300 new_version(), |
293 base::Bind(&ServiceWorkerRegisterJob::OnStoreRegistrationComplete, | 301 base::Bind(&ServiceWorkerRegisterJob::OnStoreRegistrationComplete, |
294 weak_factory_.GetWeakPtr())); | 302 weak_factory_.GetWeakPtr())); |
295 } | 303 } |
296 | 304 |
297 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete( | 305 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete( |
298 ServiceWorkerStatusCode status) { | 306 ServiceWorkerStatusCode status) { |
299 if (status != SERVICE_WORKER_OK) { | 307 if (status != SERVICE_WORKER_OK) { |
308 new_version()->SetStatus(ServiceWorkerVersion::REDUNDANT); | |
309 registration()->SetInstallingVersion(NULL); | |
300 Complete(status); | 310 Complete(status); |
301 return; | 311 return; |
302 } | 312 } |
313 | |
314 // "9. If registration.waitingWorker is not null, then:..." | |
falken
2014/07/04 09:30:49
it looks like we don't actually do this step. Make
nhiroki
2014/07/04 10:37:26
Done.
| |
315 // "10. Set registration.waitingWorker to registration.installingworker." | |
316 // "11. Set registration.installing_version to null." | |
falken
2014/07/04 09:30:49
"installingWorker"
nhiroki
2014/07/04 10:37:26
Done.
| |
317 DisassociateVersionFromDocuments(context_, new_version()); | |
303 registration()->SetWaitingVersion(new_version()); | 318 registration()->SetWaitingVersion(new_version()); |
319 AssociateWaitingVersionToDocuments(context_, new_version()); | |
320 | |
321 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker | |
322 // and "installed" as the arguments." | |
323 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED); | |
304 ActivateAndContinue(); | 324 ActivateAndContinue(); |
305 } | 325 } |
306 | 326 |
307 // This function corresponds to the spec's _Activate algorithm. | 327 // This function corresponds to the spec's _Activate algorithm. |
308 void ServiceWorkerRegisterJob::ActivateAndContinue() { | 328 void ServiceWorkerRegisterJob::ActivateAndContinue() { |
309 SetPhase(ACTIVATE); | 329 SetPhase(ACTIVATE); |
310 | 330 |
311 // "If existingWorker is not null, then: wait for exitingWorker to finish | 331 // "4. If existingWorker is not null, then: wait for exitingWorker to finish |
312 // handling any in-progress requests." | 332 // handling any in-progress requests." |
313 // See if we already have an active_version for the scope and it has | 333 // See if we already have an active_version for the scope and it has |
314 // controllee documents (if so activating the new version should wait | 334 // controllee documents (if so activating the new version should wait |
315 // until we have no documents controlled by the version). | 335 // until we have no documents controlled by the version). |
316 if (registration()->active_version() && | 336 if (registration()->active_version() && |
317 registration()->active_version()->HasControllee()) { | 337 registration()->active_version()->HasControllee()) { |
318 // TODO(kinuko,falken): Currently we immediately return if the existing | 338 // TODO(kinuko,falken): Currently we immediately return if the existing |
319 // registration already has an active version, so we shouldn't come | 339 // registration already has an active version, so we shouldn't come |
320 // this way. | 340 // this way. |
321 NOTREACHED(); | 341 NOTREACHED(); |
322 // TODO(falken): Register an continuation task to wait for NoControllees | 342 // TODO(falken): Register an continuation task to wait for NoControllees |
323 // notification so that we can resume activation later (see comments | 343 // notification so that we can resume activation later (see comments |
324 // in ServiceWorkerVersion::RemoveControllee). | 344 // in ServiceWorkerVersion::RemoveControllee). |
falken
2014/07/04 09:30:49
You can remove the (see comments...) part, those c
nhiroki
2014/07/04 10:37:26
Done.
| |
325 Complete(SERVICE_WORKER_OK); | 345 Complete(SERVICE_WORKER_OK); |
326 return; | 346 return; |
327 } | 347 } |
328 | 348 |
329 // "Set serviceWorkerRegistration.waitingWorker to null." | 349 // "5. Set serviceWorkerRegistration.activeWorker to activatingWorker." |
330 // "Set serviceWorkerRegistration.activeWorker to activatingWorker." | 350 // "6. Set serviceWorkerRegistration.waitingWorker to null." |
331 registration()->SetActiveVersion(new_version()); | 351 registration()->SetActiveVersion(new_version()); |
332 | 352 |
333 // "Set serviceWorkerRegistration.activeWorker._state to activating." | 353 // "7. Run the [[UpdateState]] algorithm passing registration.activeWorker and |
334 // "Fire activate event on the associated ServiceWorkerGlobalScope object." | 354 // "activating" as arguments." |
335 // "Set serviceWorkerRegistration.activeWorker._state to active." | 355 new_version()->SetStatus(ServiceWorkerVersion::ACTIVATING); |
356 | |
357 // TODO(nhiroki): "8. Fire a simple event named controllerchange..." | |
358 | |
359 // "9. Fire an event named activate..." | |
336 new_version()->DispatchActivateEvent( | 360 new_version()->DispatchActivateEvent( |
337 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, | 361 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, |
338 weak_factory_.GetWeakPtr())); | 362 weak_factory_.GetWeakPtr())); |
339 } | 363 } |
340 | 364 |
341 void ServiceWorkerRegisterJob::OnActivateFinished( | 365 void ServiceWorkerRegisterJob::OnActivateFinished( |
342 ServiceWorkerStatusCode status) { | 366 ServiceWorkerStatusCode status) { |
343 // "If any handler called waitUntil()..." and the resulting promise | |
344 // is rejected, abort. | |
345 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is | 367 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is |
346 // unexpectedly terminated) we may want to retry sending the event again. | 368 // unexpectedly terminated) we may want to retry sending the event again. |
347 if (status != SERVICE_WORKER_OK) { | 369 if (status != SERVICE_WORKER_OK) { |
370 // "11. If activateFailed is true, then:..." | |
371 new_version()->SetStatus(ServiceWorkerVersion::REDUNDANT); | |
348 registration()->SetActiveVersion(NULL); | 372 registration()->SetActiveVersion(NULL); |
349 Complete(status); | 373 Complete(status); |
350 return; | 374 return; |
351 } | 375 } |
376 | |
377 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker | |
378 // and "activated" as the arguments." | |
379 new_version()->SetStatus(ServiceWorkerVersion::ACTIVE); | |
352 context_->storage()->UpdateToActiveState( | 380 context_->storage()->UpdateToActiveState( |
353 registration(), | 381 registration(), |
354 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 382 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
355 Complete(SERVICE_WORKER_OK); | 383 Complete(SERVICE_WORKER_OK); |
356 } | 384 } |
357 | 385 |
358 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { | 386 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { |
359 CompleteInternal(status); | 387 CompleteInternal(status); |
360 context_->job_coordinator()->FinishJob(pattern_, this); | 388 context_->job_coordinator()->FinishJob(pattern_, this); |
361 } | 389 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
433 if (ServiceWorkerUtils::ScopeMatches(version->scope(), | 461 if (ServiceWorkerUtils::ScopeMatches(version->scope(), |
434 host->document_url())) { | 462 host->document_url())) { |
435 if (!host->CanAssociateVersion(version)) | 463 if (!host->CanAssociateVersion(version)) |
436 continue; | 464 continue; |
437 host->SetInstallingVersion(version); | 465 host->SetInstallingVersion(version); |
438 } | 466 } |
439 } | 467 } |
440 } | 468 } |
441 | 469 |
442 // static | 470 // static |
471 void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments( | |
472 base::WeakPtr<ServiceWorkerContextCore> context, | |
473 ServiceWorkerVersion* version) { | |
474 DCHECK(context); | |
475 DCHECK(version); | |
476 | |
477 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | |
478 context->GetProviderHostIterator(); | |
479 !it->IsAtEnd(); it->Advance()) { | |
falken
2014/07/04 09:30:49
extra spaces
nhiroki
2014/07/04 10:37:26
Done.
| |
480 ServiceWorkerProviderHost* host = it->GetProviderHost(); | |
481 if (ServiceWorkerUtils::ScopeMatches(version->scope(), | |
482 host->document_url())) { | |
483 if (!host->CanAssociateVersion(version)) | |
484 continue; | |
485 host->SetWaitingVersion(version); | |
486 } | |
487 } | |
488 } | |
489 | |
490 // static | |
443 void ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( | 491 void ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( |
444 base::WeakPtr<ServiceWorkerContextCore> context, | 492 base::WeakPtr<ServiceWorkerContextCore> context, |
445 ServiceWorkerVersion* version) { | 493 ServiceWorkerVersion* version) { |
446 DCHECK(context); | 494 DCHECK(context); |
447 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 495 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
448 context->GetProviderHostIterator(); | 496 context->GetProviderHostIterator(); |
449 !it->IsAtEnd(); it->Advance()) { | 497 !it->IsAtEnd(); it->Advance()) { |
450 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 498 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
451 host->UnsetVersion(version); | 499 host->UnsetVersion(version); |
452 } | 500 } |
453 } | 501 } |
454 | 502 |
455 } // namespace content | 503 } // namespace content |
OLD | NEW |