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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
| 9 #include <vector> |
| 10 |
9 #include "base/location.h" | 11 #include "base/location.h" |
10 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
11 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
12 #include "content/browser/service_worker/service_worker_context_core.h" | 14 #include "content/browser/service_worker/service_worker_context_core.h" |
13 #include "content/browser/service_worker/service_worker_job_coordinator.h" | 15 #include "content/browser/service_worker/service_worker_job_coordinator.h" |
14 #include "content/browser/service_worker/service_worker_metrics.h" | 16 #include "content/browser/service_worker/service_worker_metrics.h" |
15 #include "content/browser/service_worker/service_worker_registration.h" | 17 #include "content/browser/service_worker/service_worker_registration.h" |
16 #include "content/browser/service_worker/service_worker_storage.h" | 18 #include "content/browser/service_worker/service_worker_storage.h" |
17 #include "content/browser/service_worker/service_worker_write_to_cache_job.h" | |
18 #include "content/common/service_worker/service_worker_messages.h" | 19 #include "content/common/service_worker/service_worker_messages.h" |
19 #include "content/common/service_worker/service_worker_types.h" | 20 #include "content/common/service_worker/service_worker_types.h" |
20 #include "content/common/service_worker/service_worker_utils.h" | 21 #include "content/common/service_worker/service_worker_utils.h" |
21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
22 #include "net/base/net_errors.h" | 23 #include "net/base/net_errors.h" |
23 | 24 |
24 namespace content { | 25 namespace content { |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 if (version_id == kInvalidServiceWorkerVersionId) { | 338 if (version_id == kInvalidServiceWorkerVersionId) { |
338 Complete(SERVICE_WORKER_ERROR_ABORT); | 339 Complete(SERVICE_WORKER_ERROR_ABORT); |
339 return; | 340 return; |
340 } | 341 } |
341 | 342 |
342 // "Let worker be a new ServiceWorker object..." and start | 343 // "Let worker be a new ServiceWorker object..." and start |
343 // the worker. | 344 // the worker. |
344 set_new_version(new ServiceWorkerVersion(registration(), script_url_, | 345 set_new_version(new ServiceWorkerVersion(registration(), script_url_, |
345 version_id, context_)); | 346 version_id, context_)); |
346 new_version()->set_force_bypass_cache_for_scripts(force_bypass_cache_); | 347 new_version()->set_force_bypass_cache_for_scripts(force_bypass_cache_); |
347 if (registration()->has_installed_version() && !skip_script_comparison_) { | 348 new_version()->set_skip_script_comparison(skip_script_comparison_); |
348 new_version()->set_pause_after_download(true); | |
349 new_version()->embedded_worker()->AddListener(this); | |
350 } else { | |
351 new_version()->set_pause_after_download(false); | |
352 } | |
353 new_version()->StartWorker( | 349 new_version()->StartWorker( |
354 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, | 350 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, |
355 weak_factory_.GetWeakPtr())); | 351 weak_factory_.GetWeakPtr())); |
356 } | 352 } |
357 | 353 |
358 void ServiceWorkerRegisterJob::OnStartWorkerFinished( | 354 void ServiceWorkerRegisterJob::OnStartWorkerFinished( |
359 ServiceWorkerStatusCode status) { | 355 ServiceWorkerStatusCode status) { |
360 // Bump the last update check time only when the register/update job fetched | 356 // Bump the last update check time only when the register/update job fetched |
361 // the version having bypassed the network cache. We assume that the | 357 // the version having bypassed the network cache. We assume that the |
362 // BYPASS_CACHE flag evicts an existing cache entry, so even if the install | 358 // BYPASS_CACHE flag evicts an existing cache entry, so even if the install |
363 // ultimately failed for whatever reason, we know the version in the HTTP | 359 // ultimately failed for whatever reason, we know the version in the HTTP |
364 // cache is not stale, so it's OK to bump the update check time. | 360 // cache is not stale, so it's OK to bump the update check time. |
365 if (new_version()->embedded_worker()->network_accessed_for_script() || | 361 if (new_version()->embedded_worker()->network_accessed_for_script() || |
366 new_version()->force_bypass_cache_for_scripts() || | 362 new_version()->force_bypass_cache_for_scripts() || |
367 registration()->last_update_check().is_null()) { | 363 registration()->last_update_check().is_null()) { |
368 registration()->set_last_update_check(base::Time::Now()); | 364 registration()->set_last_update_check(base::Time::Now()); |
369 | 365 |
370 if (registration()->has_installed_version()) | 366 if (registration()->waiting_version() || registration()->active_version()) |
371 context_->storage()->UpdateLastUpdateCheckTime(registration()); | 367 context_->storage()->UpdateLastUpdateCheckTime(registration()); |
372 } | 368 } |
373 | 369 |
374 if (status == SERVICE_WORKER_OK) { | 370 if (status == SERVICE_WORKER_OK) { |
375 InstallAndContinue(); | 371 InstallAndContinue(); |
376 return; | 372 return; |
377 } | 373 } |
378 | 374 |
| 375 // The updated worker is identical to the incumbent. |
| 376 if (status == SERVICE_WORKER_ERROR_EXISTS) { |
| 377 ResolvePromise(SERVICE_WORKER_OK, std::string(), registration()); |
| 378 Complete(status, "The updated worker is identical to the incumbent."); |
| 379 return; |
| 380 } |
| 381 |
379 // "If serviceWorker fails to start up..." then reject the promise with an | 382 // "If serviceWorker fails to start up..." then reject the promise with an |
380 // error and abort. | 383 // error and abort. |
381 if (status == SERVICE_WORKER_ERROR_TIMEOUT) { | 384 if (status == SERVICE_WORKER_ERROR_TIMEOUT) { |
382 Complete(status, "Timed out while trying to start the Service Worker."); | 385 Complete(status, "Timed out while trying to start the Service Worker."); |
383 return; | 386 return; |
384 } | 387 } |
385 | 388 |
386 const net::URLRequestStatus& main_script_status = | 389 const net::URLRequestStatus& main_script_status = |
387 new_version()->script_cache_map()->main_script_status(); | 390 new_version()->script_cache_map()->main_script_status(); |
388 std::string message; | 391 std::string message; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status, | 500 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status, |
498 const std::string& status_message) { | 501 const std::string& status_message) { |
499 CompleteInternal(status, status_message); | 502 CompleteInternal(status, status_message); |
500 context_->job_coordinator()->FinishJob(pattern_, this); | 503 context_->job_coordinator()->FinishJob(pattern_, this); |
501 } | 504 } |
502 | 505 |
503 void ServiceWorkerRegisterJob::CompleteInternal( | 506 void ServiceWorkerRegisterJob::CompleteInternal( |
504 ServiceWorkerStatusCode status, | 507 ServiceWorkerStatusCode status, |
505 const std::string& status_message) { | 508 const std::string& status_message) { |
506 SetPhase(COMPLETE); | 509 SetPhase(COMPLETE); |
507 | |
508 if (new_version()) { | |
509 new_version()->set_pause_after_download(false); | |
510 new_version()->embedded_worker()->RemoveListener(this); | |
511 } | |
512 | |
513 if (status != SERVICE_WORKER_OK) { | 510 if (status != SERVICE_WORKER_OK) { |
514 if (registration()) { | 511 if (registration()) { |
515 if (should_uninstall_on_failure_) | 512 if (should_uninstall_on_failure_) |
516 registration()->ClearWhenReady(); | 513 registration()->ClearWhenReady(); |
517 if (new_version()) { | 514 if (new_version()) { |
518 if (status == SERVICE_WORKER_ERROR_EXISTS) | 515 if (status == SERVICE_WORKER_ERROR_EXISTS) |
519 new_version()->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_EXISTS); | 516 new_version()->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_EXISTS); |
520 else | 517 else |
521 new_version()->ReportError(status, status_message); | 518 new_version()->ReportError(status, status_message); |
522 registration()->UnsetVersion(new_version()); | 519 registration()->UnsetVersion(new_version()); |
523 new_version()->Doom(); | 520 new_version()->Doom(); |
524 } | 521 } |
525 if (!registration()->waiting_version() && | 522 if (!registration()->waiting_version() && |
526 !registration()->active_version()) { | 523 !registration()->active_version()) { |
527 registration()->NotifyRegistrationFailed(); | 524 registration()->NotifyRegistrationFailed(); |
528 context_->storage()->DeleteRegistration( | 525 context_->storage()->DeleteRegistration( |
529 registration()->id(), | 526 registration()->id(), |
530 registration()->pattern().GetOrigin(), | 527 registration()->pattern().GetOrigin(), |
531 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 528 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
532 } | 529 } |
533 } | 530 } |
534 if (!is_promise_resolved_) | 531 if (!is_promise_resolved_) |
535 ResolvePromise(status, status_message, NULL); | 532 ResolvePromise(status, status_message, NULL); |
536 } | 533 } |
537 DCHECK(callbacks_.empty()); | 534 DCHECK(callbacks_.empty()); |
538 if (registration()) { | 535 if (registration()) { |
539 context_->storage()->NotifyDoneInstallingRegistration( | 536 context_->storage()->NotifyDoneInstallingRegistration( |
540 registration(), new_version(), status); | 537 registration(), new_version(), status); |
541 if (registration()->has_installed_version()) | 538 if (registration()->waiting_version() || registration()->active_version()) |
542 registration()->set_is_uninstalled(false); | 539 registration()->set_is_uninstalled(false); |
543 } | 540 } |
544 } | 541 } |
545 | 542 |
546 void ServiceWorkerRegisterJob::ResolvePromise( | 543 void ServiceWorkerRegisterJob::ResolvePromise( |
547 ServiceWorkerStatusCode status, | 544 ServiceWorkerStatusCode status, |
548 const std::string& status_message, | 545 const std::string& status_message, |
549 ServiceWorkerRegistration* registration) { | 546 ServiceWorkerRegistration* registration) { |
550 DCHECK(!is_promise_resolved_); | 547 DCHECK(!is_promise_resolved_); |
551 | 548 |
(...skipping 18 matching lines...) Expand all Loading... |
570 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 567 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
571 if (host->IsHostToRunningServiceWorker()) | 568 if (host->IsHostToRunningServiceWorker()) |
572 continue; | 569 continue; |
573 if (!ServiceWorkerUtils::ScopeMatches(registration->pattern(), | 570 if (!ServiceWorkerUtils::ScopeMatches(registration->pattern(), |
574 host->document_url())) | 571 host->document_url())) |
575 continue; | 572 continue; |
576 host->AddMatchingRegistration(registration); | 573 host->AddMatchingRegistration(registration); |
577 } | 574 } |
578 } | 575 } |
579 | 576 |
580 void ServiceWorkerRegisterJob::OnScriptLoaded() { | |
581 DCHECK(new_version()->pause_after_download()); | |
582 new_version()->set_pause_after_download(false); | |
583 net::URLRequestStatus status = | |
584 new_version()->script_cache_map()->main_script_status(); | |
585 if (!status.is_success()) { | |
586 // OnScriptLoaded signifies a successful network load, which translates into | |
587 // a script cache error only in the byte-for-byte identical case. | |
588 DCHECK_EQ(status.error(), | |
589 ServiceWorkerWriteToCacheJob::kIdenticalScriptError); | |
590 ResolvePromise(SERVICE_WORKER_OK, std::string(), registration()); | |
591 Complete(SERVICE_WORKER_ERROR_EXISTS, | |
592 "The updated worker is identical to the incumbent."); | |
593 return; | |
594 } | |
595 | |
596 new_version()->embedded_worker()->ResumeAfterDownload(); | |
597 } | |
598 | |
599 } // namespace content | 577 } // namespace content |
OLD | NEW |