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