Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: content/browser/service_worker/service_worker_register_job.cc

Issue 369063004: ServiceWorker: SWRegisterJob should manage status of SWVersion (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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:..."
285 Complete(status); 291 Complete(status);
286 return; 292 return;
287 } 293 }
288 294
289 SetPhase(STORE); 295 SetPhase(STORE);
290 context_->storage()->StoreRegistration( 296 context_->storage()->StoreRegistration(
291 registration(), 297 registration(),
292 new_version(), 298 new_version(),
293 base::Bind(&ServiceWorkerRegisterJob::OnStoreRegistrationComplete, 299 base::Bind(&ServiceWorkerRegisterJob::OnStoreRegistrationComplete,
294 weak_factory_.GetWeakPtr())); 300 weak_factory_.GetWeakPtr()));
295 } 301 }
296 302
297 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete( 303 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete(
298 ServiceWorkerStatusCode status) { 304 ServiceWorkerStatusCode status) {
299 if (status != SERVICE_WORKER_OK) { 305 if (status != SERVICE_WORKER_OK) {
300 Complete(status); 306 Complete(status);
301 return; 307 return;
302 } 308 }
309
310 // TODO(nhiroki): "9. If registration.waitingWorker is not null, then:..."
311
312 // "10. Set registration.waitingWorker to registration.installingWorker."
313 // "11. Set registration.installingWorker to null."
314 DisassociateVersionFromDocuments(context_, new_version());
303 registration()->SetWaitingVersion(new_version()); 315 registration()->SetWaitingVersion(new_version());
316 AssociateWaitingVersionToDocuments(context_, new_version());
317
318 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker
319 // and "installed" as the arguments."
320 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED);
304 ActivateAndContinue(); 321 ActivateAndContinue();
305 } 322 }
306 323
307 // This function corresponds to the spec's _Activate algorithm. 324 // This function corresponds to the spec's _Activate algorithm.
308 void ServiceWorkerRegisterJob::ActivateAndContinue() { 325 void ServiceWorkerRegisterJob::ActivateAndContinue() {
309 SetPhase(ACTIVATE); 326 SetPhase(ACTIVATE);
310 327
311 // "If existingWorker is not null, then: wait for exitingWorker to finish 328 // "4. If existingWorker is not null, then: wait for exitingWorker to finish
312 // handling any in-progress requests." 329 // handling any in-progress requests."
313 // See if we already have an active_version for the scope and it has 330 // 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 331 // controllee documents (if so activating the new version should wait
315 // until we have no documents controlled by the version). 332 // until we have no documents controlled by the version).
316 if (registration()->active_version() && 333 if (registration()->active_version() &&
317 registration()->active_version()->HasControllee()) { 334 registration()->active_version()->HasControllee()) {
318 // TODO(kinuko,falken): Currently we immediately return if the existing 335 // TODO(kinuko,falken): Currently we immediately return if the existing
319 // registration already has an active version, so we shouldn't come 336 // registration already has an active version, so we shouldn't come
320 // this way. 337 // this way.
321 NOTREACHED(); 338 NOTREACHED();
322 // TODO(falken): Register an continuation task to wait for NoControllees 339 // TODO(falken): Register an continuation task to wait for NoControllees
323 // notification so that we can resume activation later (see comments 340 // notification so that we can resume activation later.
324 // in ServiceWorkerVersion::RemoveControllee).
325 Complete(SERVICE_WORKER_OK); 341 Complete(SERVICE_WORKER_OK);
326 return; 342 return;
327 } 343 }
328 344
329 // "Set serviceWorkerRegistration.waitingWorker to null." 345 // "5. Set serviceWorkerRegistration.activeWorker to activatingWorker."
330 // "Set serviceWorkerRegistration.activeWorker to activatingWorker." 346 // "6. Set serviceWorkerRegistration.waitingWorker to null."
331 registration()->SetActiveVersion(new_version()); 347 registration()->SetActiveVersion(new_version());
332 348
333 // "Set serviceWorkerRegistration.activeWorker._state to activating." 349 // "7. Run the [[UpdateState]] algorithm passing registration.activeWorker and
334 // "Fire activate event on the associated ServiceWorkerGlobalScope object." 350 // "activating" as arguments."
335 // "Set serviceWorkerRegistration.activeWorker._state to active." 351 new_version()->SetStatus(ServiceWorkerVersion::ACTIVATING);
352
353 // TODO(nhiroki): "8. Fire a simple event named controllerchange..."
354
355 // "9. Fire an event named activate..."
336 new_version()->DispatchActivateEvent( 356 new_version()->DispatchActivateEvent(
337 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, 357 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished,
338 weak_factory_.GetWeakPtr())); 358 weak_factory_.GetWeakPtr()));
339 } 359 }
340 360
341 void ServiceWorkerRegisterJob::OnActivateFinished( 361 void ServiceWorkerRegisterJob::OnActivateFinished(
342 ServiceWorkerStatusCode status) { 362 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 363 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is
346 // unexpectedly terminated) we may want to retry sending the event again. 364 // unexpectedly terminated) we may want to retry sending the event again.
347 if (status != SERVICE_WORKER_OK) { 365 if (status != SERVICE_WORKER_OK) {
348 registration()->SetActiveVersion(NULL); 366 // "11. If activateFailed is true, then:..."
349 Complete(status); 367 Complete(status);
350 return; 368 return;
351 } 369 }
370
371 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker
372 // and "activated" as the arguments."
373 new_version()->SetStatus(ServiceWorkerVersion::ACTIVATED);
352 context_->storage()->UpdateToActiveState( 374 context_->storage()->UpdateToActiveState(
353 registration(), 375 registration(),
354 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 376 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
355 Complete(SERVICE_WORKER_OK); 377 Complete(SERVICE_WORKER_OK);
356 } 378 }
357 379
358 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { 380 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) {
359 CompleteInternal(status); 381 CompleteInternal(status);
360 context_->job_coordinator()->FinishJob(pattern_, this); 382 context_->job_coordinator()->FinishJob(pattern_, this);
361 } 383 }
362 384
363 void ServiceWorkerRegisterJob::CompleteInternal( 385 void ServiceWorkerRegisterJob::CompleteInternal(
364 ServiceWorkerStatusCode status) { 386 ServiceWorkerStatusCode status) {
365 SetPhase(COMPLETE); 387 SetPhase(COMPLETE);
366 if (status != SERVICE_WORKER_OK) { 388 if (status != SERVICE_WORKER_OK) {
367 if (registration()) { 389 if (registration()) {
368 if (new_version()) { 390 if (new_version()) {
391 new_version()->SetStatus(ServiceWorkerVersion::REDUNDANT);
369 DisassociateVersionFromDocuments(context_, new_version()); 392 DisassociateVersionFromDocuments(context_, new_version());
370 registration()->UnsetVersion(new_version()); 393 registration()->UnsetVersion(new_version());
371 } 394 }
372 if (!registration()->active_version()) { 395 if (!registration()->active_version()) {
373 context_->storage()->DeleteRegistration( 396 context_->storage()->DeleteRegistration(
374 registration()->id(), 397 registration()->id(),
375 registration()->script_url().GetOrigin(), 398 registration()->script_url().GetOrigin(),
376 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 399 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
377 } 400 }
378 } 401 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 444
422 // static 445 // static
423 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments( 446 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments(
424 base::WeakPtr<ServiceWorkerContextCore> context, 447 base::WeakPtr<ServiceWorkerContextCore> context,
425 ServiceWorkerVersion* version) { 448 ServiceWorkerVersion* version) {
426 DCHECK(context); 449 DCHECK(context);
427 DCHECK(version); 450 DCHECK(version);
428 451
429 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = 452 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
430 context->GetProviderHostIterator(); 453 context->GetProviderHostIterator();
431 !it->IsAtEnd(); it->Advance()) { 454 !it->IsAtEnd(); it->Advance()) {
432 ServiceWorkerProviderHost* host = it->GetProviderHost(); 455 ServiceWorkerProviderHost* host = it->GetProviderHost();
433 if (ServiceWorkerUtils::ScopeMatches(version->scope(), 456 if (ServiceWorkerUtils::ScopeMatches(version->scope(),
434 host->document_url())) { 457 host->document_url())) {
435 if (!host->CanAssociateVersion(version)) 458 if (!host->CanAssociateVersion(version))
436 continue; 459 continue;
437 host->SetInstallingVersion(version); 460 host->SetInstallingVersion(version);
438 } 461 }
439 } 462 }
440 } 463 }
441 464
442 // static 465 // static
466 void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments(
467 base::WeakPtr<ServiceWorkerContextCore> context,
468 ServiceWorkerVersion* version) {
469 DCHECK(context);
470 DCHECK(version);
471
472 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
473 context->GetProviderHostIterator();
474 !it->IsAtEnd(); it->Advance()) {
475 ServiceWorkerProviderHost* host = it->GetProviderHost();
476 if (ServiceWorkerUtils::ScopeMatches(version->scope(),
477 host->document_url())) {
478 if (!host->CanAssociateVersion(version))
479 continue;
480 host->SetWaitingVersion(version);
481 }
482 }
483 }
484
485 // static
443 void ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( 486 void ServiceWorkerRegisterJob::DisassociateVersionFromDocuments(
444 base::WeakPtr<ServiceWorkerContextCore> context, 487 base::WeakPtr<ServiceWorkerContextCore> context,
445 ServiceWorkerVersion* version) { 488 ServiceWorkerVersion* version) {
446 DCHECK(context); 489 DCHECK(context);
447 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = 490 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
448 context->GetProviderHostIterator(); 491 context->GetProviderHostIterator();
449 !it->IsAtEnd(); it->Advance()) { 492 !it->IsAtEnd(); it->Advance()) {
450 ServiceWorkerProviderHost* host = it->GetProviderHost(); 493 ServiceWorkerProviderHost* host = it->GetProviderHost();
451 host->UnsetVersion(version); 494 host->UnsetVersion(version);
452 } 495 }
453 } 496 }
454 497
455 } // namespace content 498 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698