| 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_version.h" | 5 #include "content/browser/service_worker/service_worker_version.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "base/strings/string16.h" | 21 #include "base/strings/string16.h" |
| 22 #include "base/strings/utf_string_conversions.h" | 22 #include "base/strings/utf_string_conversions.h" |
| 23 #include "base/threading/thread_task_runner_handle.h" | 23 #include "base/threading/thread_task_runner_handle.h" |
| 24 #include "base/time/time.h" | 24 #include "base/time/time.h" |
| 25 #include "content/browser/bad_message.h" | 25 #include "content/browser/bad_message.h" |
| 26 #include "content/browser/child_process_security_policy_impl.h" | 26 #include "content/browser/child_process_security_policy_impl.h" |
| 27 #include "content/browser/message_port_message_filter.h" | 27 #include "content/browser/message_port_message_filter.h" |
| 28 #include "content/browser/message_port_service.h" | 28 #include "content/browser/message_port_service.h" |
| 29 #include "content/browser/service_worker/embedded_worker_instance.h" | 29 #include "content/browser/service_worker/embedded_worker_instance.h" |
| 30 #include "content/browser/service_worker/embedded_worker_registry.h" | 30 #include "content/browser/service_worker/embedded_worker_registry.h" |
| 31 #include "content/browser/service_worker/embedded_worker_status.h" |
| 31 #include "content/browser/service_worker/service_worker_client_utils.h" | 32 #include "content/browser/service_worker/service_worker_client_utils.h" |
| 32 #include "content/browser/service_worker/service_worker_context_core.h" | 33 #include "content/browser/service_worker/service_worker_context_core.h" |
| 33 #include "content/browser/service_worker/service_worker_context_wrapper.h" | 34 #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| 34 #include "content/browser/service_worker/service_worker_metrics.h" | 35 #include "content/browser/service_worker/service_worker_metrics.h" |
| 35 #include "content/browser/service_worker/service_worker_registration.h" | 36 #include "content/browser/service_worker/service_worker_registration.h" |
| 36 #include "content/common/service_worker/embedded_worker_messages.h" | 37 #include "content/common/service_worker/embedded_worker_messages.h" |
| 37 #include "content/common/service_worker/service_worker_messages.h" | 38 #include "content/common/service_worker/service_worker_messages.h" |
| 38 #include "content/common/service_worker/service_worker_type_converters.h" | 39 #include "content/common/service_worker/service_worker_type_converters.h" |
| 39 #include "content/common/service_worker/service_worker_utils.h" | 40 #include "content/common/service_worker/service_worker_utils.h" |
| 40 #include "content/public/browser/browser_thread.h" | 41 #include "content/public/browser/browser_thread.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 void RunTaskAfterStartWorker( | 97 void RunTaskAfterStartWorker( |
| 97 base::WeakPtr<ServiceWorkerVersion> version, | 98 base::WeakPtr<ServiceWorkerVersion> version, |
| 98 const StatusCallback& error_callback, | 99 const StatusCallback& error_callback, |
| 99 const base::Closure& task, | 100 const base::Closure& task, |
| 100 ServiceWorkerStatusCode status) { | 101 ServiceWorkerStatusCode status) { |
| 101 if (status != SERVICE_WORKER_OK) { | 102 if (status != SERVICE_WORKER_OK) { |
| 102 if (!error_callback.is_null()) | 103 if (!error_callback.is_null()) |
| 103 error_callback.Run(status); | 104 error_callback.Run(status); |
| 104 return; | 105 return; |
| 105 } | 106 } |
| 106 if (version->running_status() != ServiceWorkerVersion::RUNNING) { | 107 if (version->running_status() != EmbeddedWorkerStatus::RUNNING) { |
| 107 // We've tried to start the worker (and it has succeeded), but | 108 // We've tried to start the worker (and it has succeeded), but |
| 108 // it looks it's not running yet. | 109 // it looks it's not running yet. |
| 109 NOTREACHED() << "The worker's not running after successful StartWorker"; | 110 NOTREACHED() << "The worker's not running after successful StartWorker"; |
| 110 if (!error_callback.is_null()) | 111 if (!error_callback.is_null()) |
| 111 error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED); | 112 error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED); |
| 112 return; | 113 return; |
| 113 } | 114 } |
| 114 task.Run(); | 115 task.Run(); |
| 115 } | 116 } |
| 116 | 117 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 if (!start_callbacks_.empty()) { | 320 if (!start_callbacks_.empty()) { |
| 320 // RecordStartWorkerResult must be the first element of start_callbacks_. | 321 // RecordStartWorkerResult must be the first element of start_callbacks_. |
| 321 StatusCallback record_start_worker_result = start_callbacks_[0]; | 322 StatusCallback record_start_worker_result = start_callbacks_[0]; |
| 322 start_callbacks_.clear(); | 323 start_callbacks_.clear(); |
| 323 record_start_worker_result.Run(SERVICE_WORKER_ERROR_ABORT); | 324 record_start_worker_result.Run(SERVICE_WORKER_ERROR_ABORT); |
| 324 } | 325 } |
| 325 | 326 |
| 326 if (context_) | 327 if (context_) |
| 327 context_->RemoveLiveVersion(version_id_); | 328 context_->RemoveLiveVersion(version_id_); |
| 328 | 329 |
| 329 if (running_status() == STARTING || running_status() == RUNNING) | 330 if (running_status() == EmbeddedWorkerStatus::STARTING || |
| 331 running_status() == EmbeddedWorkerStatus::RUNNING) { |
| 330 embedded_worker_->Stop(); | 332 embedded_worker_->Stop(); |
| 333 } |
| 331 embedded_worker_->RemoveListener(this); | 334 embedded_worker_->RemoveListener(this); |
| 332 } | 335 } |
| 333 | 336 |
| 334 void ServiceWorkerVersion::SetStatus(Status status) { | 337 void ServiceWorkerVersion::SetStatus(Status status) { |
| 335 if (status_ == status) | 338 if (status_ == status) |
| 336 return; | 339 return; |
| 337 | 340 |
| 338 TRACE_EVENT2("ServiceWorker", "ServiceWorkerVersion::SetStatus", "Script URL", | 341 TRACE_EVENT2("ServiceWorker", "ServiceWorkerVersion::SetStatus", "Script URL", |
| 339 script_url_.spec(), "New Status", VersionStatusToString(status)); | 342 script_url_.spec(), "New Status", VersionStatusToString(status)); |
| 340 | 343 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 weak_factory_.GetWeakPtr(), purpose, status_, | 442 weak_factory_.GetWeakPtr(), purpose, status_, |
| 440 is_browser_startup_complete, callback)); | 443 is_browser_startup_complete, callback)); |
| 441 } | 444 } |
| 442 | 445 |
| 443 void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) { | 446 void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) { |
| 444 TRACE_EVENT_INSTANT2("ServiceWorker", | 447 TRACE_EVENT_INSTANT2("ServiceWorker", |
| 445 "ServiceWorkerVersion::StopWorker (instant)", | 448 "ServiceWorkerVersion::StopWorker (instant)", |
| 446 TRACE_EVENT_SCOPE_THREAD, "Script", script_url_.spec(), | 449 TRACE_EVENT_SCOPE_THREAD, "Script", script_url_.spec(), |
| 447 "Status", VersionStatusToString(status_)); | 450 "Status", VersionStatusToString(status_)); |
| 448 | 451 |
| 449 if (running_status() == STOPPED) { | 452 if (running_status() == EmbeddedWorkerStatus::STOPPED) { |
| 450 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 453 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 451 return; | 454 return; |
| 452 } | 455 } |
| 453 | 456 |
| 454 if (stop_callbacks_.empty()) { | 457 if (stop_callbacks_.empty()) { |
| 455 ServiceWorkerStatusCode status = embedded_worker_->Stop(); | 458 ServiceWorkerStatusCode status = embedded_worker_->Stop(); |
| 456 if (status != SERVICE_WORKER_OK) { | 459 if (status != SERVICE_WORKER_OK) { |
| 457 RunSoon(base::Bind(callback, status)); | 460 RunSoon(base::Bind(callback, status)); |
| 458 return; | 461 return; |
| 459 } | 462 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 event_type, error_callback, | 505 event_type, error_callback, |
| 503 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes), KILL_ON_TIMEOUT); | 506 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes), KILL_ON_TIMEOUT); |
| 504 } | 507 } |
| 505 | 508 |
| 506 int ServiceWorkerVersion::StartRequestWithCustomTimeout( | 509 int ServiceWorkerVersion::StartRequestWithCustomTimeout( |
| 507 ServiceWorkerMetrics::EventType event_type, | 510 ServiceWorkerMetrics::EventType event_type, |
| 508 const StatusCallback& error_callback, | 511 const StatusCallback& error_callback, |
| 509 const base::TimeDelta& timeout, | 512 const base::TimeDelta& timeout, |
| 510 TimeoutBehavior timeout_behavior) { | 513 TimeoutBehavior timeout_behavior) { |
| 511 OnBeginEvent(); | 514 OnBeginEvent(); |
| 512 DCHECK_EQ(RUNNING, running_status()) | 515 DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status()) |
| 513 << "Can only start a request with a running worker."; | 516 << "Can only start a request with a running worker."; |
| 514 DCHECK(event_type == ServiceWorkerMetrics::EventType::INSTALL || | 517 DCHECK(event_type == ServiceWorkerMetrics::EventType::INSTALL || |
| 515 event_type == ServiceWorkerMetrics::EventType::ACTIVATE || | 518 event_type == ServiceWorkerMetrics::EventType::ACTIVATE || |
| 516 event_type == ServiceWorkerMetrics::EventType::MESSAGE || | 519 event_type == ServiceWorkerMetrics::EventType::MESSAGE || |
| 517 status() == ACTIVATED) | 520 status() == ACTIVATED) |
| 518 << "Event of type " << static_cast<int>(event_type) | 521 << "Event of type " << static_cast<int>(event_type) |
| 519 << " can only be dispatched to an active worker: " << status(); | 522 << " can only be dispatched to an active worker: " << status(); |
| 520 | 523 |
| 521 PendingRequest<StatusCallback>* request = new PendingRequest<StatusCallback>( | 524 PendingRequest<StatusCallback>* request = new PendingRequest<StatusCallback>( |
| 522 error_callback, base::TimeTicks::Now(), event_type); | 525 error_callback, base::TimeTicks::Now(), event_type); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 549 // order to release worker resources soon. | 552 // order to release worker resources soon. |
| 550 StopWorkerIfIdle(); | 553 StopWorkerIfIdle(); |
| 551 } | 554 } |
| 552 return true; | 555 return true; |
| 553 } | 556 } |
| 554 | 557 |
| 555 void ServiceWorkerVersion::RunAfterStartWorker( | 558 void ServiceWorkerVersion::RunAfterStartWorker( |
| 556 ServiceWorkerMetrics::EventType purpose, | 559 ServiceWorkerMetrics::EventType purpose, |
| 557 const base::Closure& task, | 560 const base::Closure& task, |
| 558 const StatusCallback& error_callback) { | 561 const StatusCallback& error_callback) { |
| 559 if (running_status() == RUNNING) { | 562 if (running_status() == EmbeddedWorkerStatus::RUNNING) { |
| 560 DCHECK(start_callbacks_.empty()); | 563 DCHECK(start_callbacks_.empty()); |
| 561 task.Run(); | 564 task.Run(); |
| 562 return; | 565 return; |
| 563 } | 566 } |
| 564 StartWorker(purpose, | 567 StartWorker(purpose, |
| 565 base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), | 568 base::Bind(&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), |
| 566 error_callback, task)); | 569 error_callback, task)); |
| 567 } | 570 } |
| 568 | 571 |
| 569 void ServiceWorkerVersion::AddControllee( | 572 void ServiceWorkerVersion::AddControllee( |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 } | 626 } |
| 624 | 627 |
| 625 void ServiceWorkerVersion::SetStartWorkerStatusCode( | 628 void ServiceWorkerVersion::SetStartWorkerStatusCode( |
| 626 ServiceWorkerStatusCode status) { | 629 ServiceWorkerStatusCode status) { |
| 627 start_worker_status_ = status; | 630 start_worker_status_ = status; |
| 628 } | 631 } |
| 629 | 632 |
| 630 void ServiceWorkerVersion::Doom() { | 633 void ServiceWorkerVersion::Doom() { |
| 631 DCHECK(!HasControllee()); | 634 DCHECK(!HasControllee()); |
| 632 SetStatus(REDUNDANT); | 635 SetStatus(REDUNDANT); |
| 633 if (running_status() == STARTING || running_status() == RUNNING) { | 636 if (running_status() == EmbeddedWorkerStatus::STARTING || |
| 637 running_status() == EmbeddedWorkerStatus::RUNNING) { |
| 634 if (embedded_worker()->devtools_attached()) | 638 if (embedded_worker()->devtools_attached()) |
| 635 stop_when_devtools_detached_ = true; | 639 stop_when_devtools_detached_ = true; |
| 636 else | 640 else |
| 637 embedded_worker_->Stop(); | 641 embedded_worker_->Stop(); |
| 638 } | 642 } |
| 639 if (!context_) | 643 if (!context_) |
| 640 return; | 644 return; |
| 641 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 645 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
| 642 script_cache_map_.GetResources(&resources); | 646 script_cache_map_.GetResources(&resources); |
| 643 context_->storage()->PurgeResources(resources); | 647 context_->storage()->PurgeResources(resources); |
| 644 } | 648 } |
| 645 | 649 |
| 646 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { | 650 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { |
| 647 embedded_worker()->set_devtools_attached(attached); | 651 embedded_worker()->set_devtools_attached(attached); |
| 648 if (stop_when_devtools_detached_ && !attached) { | 652 if (stop_when_devtools_detached_ && !attached) { |
| 649 DCHECK_EQ(REDUNDANT, status()); | 653 DCHECK_EQ(REDUNDANT, status()); |
| 650 if (running_status() == STARTING || running_status() == RUNNING) | 654 if (running_status() == EmbeddedWorkerStatus::STARTING || |
| 655 running_status() == EmbeddedWorkerStatus::RUNNING) { |
| 651 embedded_worker_->Stop(); | 656 embedded_worker_->Stop(); |
| 657 } |
| 652 return; | 658 return; |
| 653 } | 659 } |
| 654 if (attached) { | 660 if (attached) { |
| 655 // TODO(falken): Canceling the timeouts when debugging could cause | 661 // TODO(falken): Canceling the timeouts when debugging could cause |
| 656 // heisenbugs; we should instead run them as normal show an educational | 662 // heisenbugs; we should instead run them as normal show an educational |
| 657 // message in DevTools when they occur. crbug.com/470419 | 663 // message in DevTools when they occur. crbug.com/470419 |
| 658 | 664 |
| 659 // Don't record the startup time metric once DevTools is attached. | 665 // Don't record the startup time metric once DevTools is attached. |
| 660 ClearTick(&start_time_); | 666 ClearTick(&start_time_); |
| 661 skip_recording_startup_time_ = true; | 667 skip_recording_startup_time_ = true; |
| 662 | 668 |
| 663 // Cancel request timeouts. | 669 // Cancel request timeouts. |
| 664 SetAllRequestExpirations(base::TimeTicks()); | 670 SetAllRequestExpirations(base::TimeTicks()); |
| 665 return; | 671 return; |
| 666 } | 672 } |
| 667 if (!start_callbacks_.empty()) { | 673 if (!start_callbacks_.empty()) { |
| 668 // Reactivate the timer for start timeout. | 674 // Reactivate the timer for start timeout. |
| 669 DCHECK(timeout_timer_.IsRunning()); | 675 DCHECK(timeout_timer_.IsRunning()); |
| 670 DCHECK(running_status() == STARTING || running_status() == STOPPING) | 676 DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || |
| 671 << running_status(); | 677 running_status() == EmbeddedWorkerStatus::STOPPING) |
| 678 << static_cast<int>(running_status()); |
| 672 RestartTick(&start_time_); | 679 RestartTick(&start_time_); |
| 673 } | 680 } |
| 674 | 681 |
| 675 // Reactivate request timeouts, setting them all to the same expiration time. | 682 // Reactivate request timeouts, setting them all to the same expiration time. |
| 676 SetAllRequestExpirations( | 683 SetAllRequestExpirations( |
| 677 base::TimeTicks::Now() + | 684 base::TimeTicks::Now() + |
| 678 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)); | 685 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)); |
| 679 } | 686 } |
| 680 | 687 |
| 681 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( | 688 void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request", | 740 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request", |
| 734 request, "Error", "Service Disconnected"); | 741 request, "Error", "Service Disconnected"); |
| 735 request->callback.Run(SERVICE_WORKER_ERROR_FAILED); | 742 request->callback.Run(SERVICE_WORKER_ERROR_FAILED); |
| 736 worker_->custom_requests_.Remove(iter.GetCurrentKey()); | 743 worker_->custom_requests_.Remove(iter.GetCurrentKey()); |
| 737 } | 744 } |
| 738 iter.Advance(); | 745 iter.Advance(); |
| 739 } | 746 } |
| 740 } | 747 } |
| 741 | 748 |
| 742 void ServiceWorkerVersion::OnThreadStarted() { | 749 void ServiceWorkerVersion::OnThreadStarted() { |
| 743 DCHECK_EQ(STARTING, running_status()); | 750 DCHECK_EQ(EmbeddedWorkerStatus::STARTING, running_status()); |
| 744 // Activate ping/pong now that JavaScript execution will start. | 751 // Activate ping/pong now that JavaScript execution will start. |
| 745 ping_controller_->Activate(); | 752 ping_controller_->Activate(); |
| 746 } | 753 } |
| 747 | 754 |
| 748 void ServiceWorkerVersion::OnStarting() { | 755 void ServiceWorkerVersion::OnStarting() { |
| 749 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); | 756 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); |
| 750 } | 757 } |
| 751 | 758 |
| 752 void ServiceWorkerVersion::OnStarted() { | 759 void ServiceWorkerVersion::OnStarted() { |
| 753 DCHECK_EQ(RUNNING, running_status()); | 760 DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status()); |
| 754 RestartTick(&idle_time_); | 761 RestartTick(&idle_time_); |
| 755 | 762 |
| 756 // Fire all start callbacks. | 763 // Fire all start callbacks. |
| 757 scoped_refptr<ServiceWorkerVersion> protect(this); | 764 scoped_refptr<ServiceWorkerVersion> protect(this); |
| 758 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); | 765 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); |
| 759 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); | 766 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); |
| 760 } | 767 } |
| 761 | 768 |
| 762 void ServiceWorkerVersion::OnStopping() { | 769 void ServiceWorkerVersion::OnStopping() { |
| 763 DCHECK(stop_time_.is_null()); | 770 DCHECK(stop_time_.is_null()); |
| 764 RestartTick(&stop_time_); | 771 RestartTick(&stop_time_); |
| 765 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", "ServiceWorkerVersion::StopWorker", | 772 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", "ServiceWorkerVersion::StopWorker", |
| 766 stop_time_.ToInternalValue(), "Script", | 773 stop_time_.ToInternalValue(), "Script", |
| 767 script_url_.spec(), "Version Status", | 774 script_url_.spec(), "Version Status", |
| 768 VersionStatusToString(status_)); | 775 VersionStatusToString(status_)); |
| 769 | 776 |
| 770 // Shorten the interval so stalling in stopped can be fixed quickly. Once the | 777 // Shorten the interval so stalling in stopped can be fixed quickly. Once the |
| 771 // worker stops, the timer is disabled. The interval will be reset to normal | 778 // worker stops, the timer is disabled. The interval will be reset to normal |
| 772 // when the worker starts up again. | 779 // when the worker starts up again. |
| 773 SetTimeoutTimerInterval( | 780 SetTimeoutTimerInterval( |
| 774 base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds)); | 781 base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds)); |
| 775 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); | 782 FOR_EACH_OBSERVER(Listener, listeners_, OnRunningStateChanged(this)); |
| 776 } | 783 } |
| 777 | 784 |
| 778 void ServiceWorkerVersion::OnStopped( | 785 void ServiceWorkerVersion::OnStopped(EmbeddedWorkerStatus old_status) { |
| 779 EmbeddedWorkerInstance::Status old_status) { | |
| 780 if (IsInstalled(status())) { | 786 if (IsInstalled(status())) { |
| 781 ServiceWorkerMetrics::RecordWorkerStopped( | 787 ServiceWorkerMetrics::RecordWorkerStopped( |
| 782 ServiceWorkerMetrics::StopStatus::NORMAL); | 788 ServiceWorkerMetrics::StopStatus::NORMAL); |
| 783 } | 789 } |
| 784 if (!stop_time_.is_null()) | 790 if (!stop_time_.is_null()) |
| 785 ServiceWorkerMetrics::RecordStopWorkerTime(GetTickDuration(stop_time_)); | 791 ServiceWorkerMetrics::RecordStopWorkerTime(GetTickDuration(stop_time_)); |
| 786 | 792 |
| 787 OnStoppedInternal(old_status); | 793 OnStoppedInternal(old_status); |
| 788 } | 794 } |
| 789 | 795 |
| 790 void ServiceWorkerVersion::OnDetached( | 796 void ServiceWorkerVersion::OnDetached(EmbeddedWorkerStatus old_status) { |
| 791 EmbeddedWorkerInstance::Status old_status) { | |
| 792 if (IsInstalled(status())) { | 797 if (IsInstalled(status())) { |
| 793 ServiceWorkerMetrics::RecordWorkerStopped( | 798 ServiceWorkerMetrics::RecordWorkerStopped( |
| 794 ServiceWorkerMetrics::StopStatus::DETACH_BY_REGISTRY); | 799 ServiceWorkerMetrics::StopStatus::DETACH_BY_REGISTRY); |
| 795 } | 800 } |
| 796 OnStoppedInternal(old_status); | 801 OnStoppedInternal(old_status); |
| 797 } | 802 } |
| 798 | 803 |
| 799 void ServiceWorkerVersion::OnScriptLoaded() { | 804 void ServiceWorkerVersion::OnScriptLoaded() { |
| 800 if (IsInstalled(status())) | 805 if (IsInstalled(status())) |
| 801 UMA_HISTOGRAM_BOOLEAN("ServiceWorker.ScriptLoadSuccess", true); | 806 UMA_HISTOGRAM_BOOLEAN("ServiceWorker.ScriptLoadSuccess", true); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 | 897 |
| 893 void ServiceWorkerVersion::OnGetClientFinished( | 898 void ServiceWorkerVersion::OnGetClientFinished( |
| 894 int request_id, | 899 int request_id, |
| 895 const ServiceWorkerClientInfo& client_info) { | 900 const ServiceWorkerClientInfo& client_info) { |
| 896 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 901 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 897 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::OnGetClient", | 902 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::OnGetClient", |
| 898 request_id, "client_type", client_info.client_type); | 903 request_id, "client_type", client_info.client_type); |
| 899 | 904 |
| 900 // When Clients.get() is called on the script evaluation phase, the running | 905 // When Clients.get() is called on the script evaluation phase, the running |
| 901 // status can be STARTING here. | 906 // status can be STARTING here. |
| 902 if (running_status() != STARTING && running_status() != RUNNING) | 907 if (running_status() != EmbeddedWorkerStatus::STARTING && |
| 908 running_status() != EmbeddedWorkerStatus::RUNNING) { |
| 903 return; | 909 return; |
| 910 } |
| 904 | 911 |
| 905 embedded_worker_->SendMessage( | 912 embedded_worker_->SendMessage( |
| 906 ServiceWorkerMsg_DidGetClient(request_id, client_info)); | 913 ServiceWorkerMsg_DidGetClient(request_id, client_info)); |
| 907 } | 914 } |
| 908 | 915 |
| 909 void ServiceWorkerVersion::OnGetClients( | 916 void ServiceWorkerVersion::OnGetClients( |
| 910 int request_id, | 917 int request_id, |
| 911 const ServiceWorkerClientQueryOptions& options) { | 918 const ServiceWorkerClientQueryOptions& options) { |
| 912 TRACE_EVENT_ASYNC_BEGIN2( | 919 TRACE_EVENT_ASYNC_BEGIN2( |
| 913 "ServiceWorker", "ServiceWorkerVersion::OnGetClients", request_id, | 920 "ServiceWorker", "ServiceWorkerVersion::OnGetClients", request_id, |
| 914 "client_type", options.client_type, "include_uncontrolled", | 921 "client_type", options.client_type, "include_uncontrolled", |
| 915 options.include_uncontrolled); | 922 options.include_uncontrolled); |
| 916 service_worker_client_utils::GetClients( | 923 service_worker_client_utils::GetClients( |
| 917 weak_factory_.GetWeakPtr(), options, | 924 weak_factory_.GetWeakPtr(), options, |
| 918 base::Bind(&ServiceWorkerVersion::OnGetClientsFinished, | 925 base::Bind(&ServiceWorkerVersion::OnGetClientsFinished, |
| 919 weak_factory_.GetWeakPtr(), request_id)); | 926 weak_factory_.GetWeakPtr(), request_id)); |
| 920 } | 927 } |
| 921 | 928 |
| 922 void ServiceWorkerVersion::OnGetClientsFinished(int request_id, | 929 void ServiceWorkerVersion::OnGetClientsFinished(int request_id, |
| 923 ServiceWorkerClients* clients) { | 930 ServiceWorkerClients* clients) { |
| 924 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 931 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 925 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::OnGetClients", | 932 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::OnGetClients", |
| 926 request_id, "The number of clients", clients->size()); | 933 request_id, "The number of clients", clients->size()); |
| 927 | 934 |
| 928 // When Clients.matchAll() is called on the script evaluation phase, the | 935 // When Clients.matchAll() is called on the script evaluation phase, the |
| 929 // running status can be STARTING here. | 936 // running status can be STARTING here. |
| 930 if (running_status() != STARTING && running_status() != RUNNING) | 937 if (running_status() != EmbeddedWorkerStatus::STARTING && |
| 938 running_status() != EmbeddedWorkerStatus::RUNNING) { |
| 931 return; | 939 return; |
| 940 } |
| 932 | 941 |
| 933 embedded_worker_->SendMessage( | 942 embedded_worker_->SendMessage( |
| 934 ServiceWorkerMsg_DidGetClients(request_id, *clients)); | 943 ServiceWorkerMsg_DidGetClients(request_id, *clients)); |
| 935 } | 944 } |
| 936 | 945 |
| 937 void ServiceWorkerVersion::OnSimpleEventResponse( | 946 void ServiceWorkerVersion::OnSimpleEventResponse( |
| 938 int request_id, | 947 int request_id, |
| 939 blink::WebServiceWorkerEventResult result) { | 948 blink::WebServiceWorkerEventResult result) { |
| 940 // Copy error callback before calling FinishRequest. | 949 // Copy error callback before calling FinishRequest. |
| 941 PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id); | 950 PendingRequest<StatusCallback>* request = custom_requests_.Lookup(request_id); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 base::Bind(&ServiceWorkerVersion::OnOpenWindowFinished, | 995 base::Bind(&ServiceWorkerVersion::OnOpenWindowFinished, |
| 987 weak_factory_.GetWeakPtr(), request_id)); | 996 weak_factory_.GetWeakPtr(), request_id)); |
| 988 } | 997 } |
| 989 | 998 |
| 990 void ServiceWorkerVersion::OnOpenWindowFinished( | 999 void ServiceWorkerVersion::OnOpenWindowFinished( |
| 991 int request_id, | 1000 int request_id, |
| 992 ServiceWorkerStatusCode status, | 1001 ServiceWorkerStatusCode status, |
| 993 const ServiceWorkerClientInfo& client_info) { | 1002 const ServiceWorkerClientInfo& client_info) { |
| 994 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1003 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 995 | 1004 |
| 996 if (running_status() != RUNNING) | 1005 if (running_status() != EmbeddedWorkerStatus::RUNNING) |
| 997 return; | 1006 return; |
| 998 | 1007 |
| 999 if (status != SERVICE_WORKER_OK) { | 1008 if (status != SERVICE_WORKER_OK) { |
| 1000 embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowError( | 1009 embedded_worker_->SendMessage(ServiceWorkerMsg_OpenWindowError( |
| 1001 request_id, "Something went wrong while trying to open the window.")); | 1010 request_id, "Something went wrong while trying to open the window.")); |
| 1002 return; | 1011 return; |
| 1003 } | 1012 } |
| 1004 | 1013 |
| 1005 embedded_worker_->SendMessage( | 1014 embedded_worker_->SendMessage( |
| 1006 ServiceWorkerMsg_OpenWindowResponse(request_id, client_info)); | 1015 ServiceWorkerMsg_OpenWindowResponse(request_id, client_info)); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 service_worker_client_utils::FocusWindowClient( | 1103 service_worker_client_utils::FocusWindowClient( |
| 1095 provider_host, base::Bind(&ServiceWorkerVersion::OnFocusClientFinished, | 1104 provider_host, base::Bind(&ServiceWorkerVersion::OnFocusClientFinished, |
| 1096 weak_factory_.GetWeakPtr(), request_id)); | 1105 weak_factory_.GetWeakPtr(), request_id)); |
| 1097 } | 1106 } |
| 1098 | 1107 |
| 1099 void ServiceWorkerVersion::OnFocusClientFinished( | 1108 void ServiceWorkerVersion::OnFocusClientFinished( |
| 1100 int request_id, | 1109 int request_id, |
| 1101 const ServiceWorkerClientInfo& client_info) { | 1110 const ServiceWorkerClientInfo& client_info) { |
| 1102 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1111 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1103 | 1112 |
| 1104 if (running_status() != RUNNING) | 1113 if (running_status() != EmbeddedWorkerStatus::RUNNING) |
| 1105 return; | 1114 return; |
| 1106 | 1115 |
| 1107 embedded_worker_->SendMessage( | 1116 embedded_worker_->SendMessage( |
| 1108 ServiceWorkerMsg_FocusClientResponse(request_id, client_info)); | 1117 ServiceWorkerMsg_FocusClientResponse(request_id, client_info)); |
| 1109 } | 1118 } |
| 1110 | 1119 |
| 1111 void ServiceWorkerVersion::OnNavigateClient(int request_id, | 1120 void ServiceWorkerVersion::OnNavigateClient(int request_id, |
| 1112 const std::string& client_uuid, | 1121 const std::string& client_uuid, |
| 1113 const GURL& url) { | 1122 const GURL& url) { |
| 1114 if (!context_) | 1123 if (!context_) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 context_, base::Bind(&ServiceWorkerVersion::OnNavigateClientFinished, | 1159 context_, base::Bind(&ServiceWorkerVersion::OnNavigateClientFinished, |
| 1151 weak_factory_.GetWeakPtr(), request_id)); | 1160 weak_factory_.GetWeakPtr(), request_id)); |
| 1152 } | 1161 } |
| 1153 | 1162 |
| 1154 void ServiceWorkerVersion::OnNavigateClientFinished( | 1163 void ServiceWorkerVersion::OnNavigateClientFinished( |
| 1155 int request_id, | 1164 int request_id, |
| 1156 ServiceWorkerStatusCode status, | 1165 ServiceWorkerStatusCode status, |
| 1157 const ServiceWorkerClientInfo& client_info) { | 1166 const ServiceWorkerClientInfo& client_info) { |
| 1158 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1167 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1159 | 1168 |
| 1160 if (running_status() != RUNNING) | 1169 if (running_status() != EmbeddedWorkerStatus::RUNNING) |
| 1161 return; | 1170 return; |
| 1162 | 1171 |
| 1163 if (status != SERVICE_WORKER_OK) { | 1172 if (status != SERVICE_WORKER_OK) { |
| 1164 embedded_worker_->SendMessage( | 1173 embedded_worker_->SendMessage( |
| 1165 ServiceWorkerMsg_NavigateClientError(request_id, GURL())); | 1174 ServiceWorkerMsg_NavigateClientError(request_id, GURL())); |
| 1166 return; | 1175 return; |
| 1167 } | 1176 } |
| 1168 | 1177 |
| 1169 embedded_worker_->SendMessage( | 1178 embedded_worker_->SendMessage( |
| 1170 ServiceWorkerMsg_NavigateClientResponse(request_id, client_info)); | 1179 ServiceWorkerMsg_NavigateClientResponse(request_id, client_info)); |
| 1171 } | 1180 } |
| 1172 | 1181 |
| 1173 void ServiceWorkerVersion::OnSkipWaiting(int request_id) { | 1182 void ServiceWorkerVersion::OnSkipWaiting(int request_id) { |
| 1174 skip_waiting_ = true; | 1183 skip_waiting_ = true; |
| 1175 if (status_ != INSTALLED) | 1184 if (status_ != INSTALLED) |
| 1176 return DidSkipWaiting(request_id); | 1185 return DidSkipWaiting(request_id); |
| 1177 | 1186 |
| 1178 if (!context_) | 1187 if (!context_) |
| 1179 return; | 1188 return; |
| 1180 ServiceWorkerRegistration* registration = | 1189 ServiceWorkerRegistration* registration = |
| 1181 context_->GetLiveRegistration(registration_id_); | 1190 context_->GetLiveRegistration(registration_id_); |
| 1182 if (!registration) | 1191 if (!registration) |
| 1183 return; | 1192 return; |
| 1184 pending_skip_waiting_requests_.push_back(request_id); | 1193 pending_skip_waiting_requests_.push_back(request_id); |
| 1185 if (pending_skip_waiting_requests_.size() == 1) | 1194 if (pending_skip_waiting_requests_.size() == 1) |
| 1186 registration->ActivateWaitingVersionWhenReady(); | 1195 registration->ActivateWaitingVersionWhenReady(); |
| 1187 } | 1196 } |
| 1188 | 1197 |
| 1189 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { | 1198 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { |
| 1190 if (running_status() == STARTING || running_status() == RUNNING) | 1199 if (running_status() == EmbeddedWorkerStatus::STARTING || |
| 1200 running_status() == EmbeddedWorkerStatus::RUNNING) { |
| 1191 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); | 1201 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); |
| 1202 } |
| 1192 } | 1203 } |
| 1193 | 1204 |
| 1194 void ServiceWorkerVersion::OnClaimClients(int request_id) { | 1205 void ServiceWorkerVersion::OnClaimClients(int request_id) { |
| 1195 if (status_ != ACTIVATING && status_ != ACTIVATED) { | 1206 if (status_ != ACTIVATING && status_ != ACTIVATED) { |
| 1196 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( | 1207 embedded_worker_->SendMessage(ServiceWorkerMsg_ClaimClientsError( |
| 1197 request_id, blink::WebServiceWorkerError::ErrorTypeState, | 1208 request_id, blink::WebServiceWorkerError::ErrorTypeState, |
| 1198 base::ASCIIToUTF16(kClaimClientsStateErrorMesage))); | 1209 base::ASCIIToUTF16(kClaimClientsStateErrorMesage))); |
| 1199 return; | 1210 return; |
| 1200 } | 1211 } |
| 1201 if (context_) { | 1212 if (context_) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 RecordStartWorkerResult(purpose, prestart_status, kInvalidTraceId, | 1291 RecordStartWorkerResult(purpose, prestart_status, kInvalidTraceId, |
| 1281 is_browser_startup_complete, | 1292 is_browser_startup_complete, |
| 1282 SERVICE_WORKER_ERROR_REDUNDANT); | 1293 SERVICE_WORKER_ERROR_REDUNDANT); |
| 1283 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT)); | 1294 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_REDUNDANT)); |
| 1284 return; | 1295 return; |
| 1285 } | 1296 } |
| 1286 | 1297 |
| 1287 MarkIfStale(); | 1298 MarkIfStale(); |
| 1288 | 1299 |
| 1289 switch (running_status()) { | 1300 switch (running_status()) { |
| 1290 case RUNNING: | 1301 case EmbeddedWorkerStatus::RUNNING: |
| 1291 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 1302 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 1292 return; | 1303 return; |
| 1293 case STARTING: | 1304 case EmbeddedWorkerStatus::STARTING: |
| 1294 DCHECK(!start_callbacks_.empty()); | 1305 DCHECK(!start_callbacks_.empty()); |
| 1295 break; | 1306 break; |
| 1296 case STOPPING: | 1307 case EmbeddedWorkerStatus::STOPPING: |
| 1297 case STOPPED: | 1308 case EmbeddedWorkerStatus::STOPPED: |
| 1298 if (start_callbacks_.empty()) { | 1309 if (start_callbacks_.empty()) { |
| 1299 int trace_id = NextTraceId(); | 1310 int trace_id = NextTraceId(); |
| 1300 TRACE_EVENT_ASYNC_BEGIN2( | 1311 TRACE_EVENT_ASYNC_BEGIN2( |
| 1301 "ServiceWorker", "ServiceWorkerVersion::StartWorker", trace_id, | 1312 "ServiceWorker", "ServiceWorkerVersion::StartWorker", trace_id, |
| 1302 "Script", script_url_.spec(), "Purpose", | 1313 "Script", script_url_.spec(), "Purpose", |
| 1303 ServiceWorkerMetrics::EventTypeToString(purpose)); | 1314 ServiceWorkerMetrics::EventTypeToString(purpose)); |
| 1304 start_callbacks_.push_back( | 1315 start_callbacks_.push_back( |
| 1305 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, | 1316 base::Bind(&ServiceWorkerVersion::RecordStartWorkerResult, |
| 1306 weak_factory_.GetWeakPtr(), purpose, prestart_status, | 1317 weak_factory_.GetWeakPtr(), purpose, prestart_status, |
| 1307 trace_id, is_browser_startup_complete)); | 1318 trace_id, is_browser_startup_complete)); |
| 1308 } | 1319 } |
| 1309 break; | 1320 break; |
| 1310 } | 1321 } |
| 1311 | 1322 |
| 1312 // Keep the live registration while starting the worker. | 1323 // Keep the live registration while starting the worker. |
| 1313 start_callbacks_.push_back( | 1324 start_callbacks_.push_back( |
| 1314 base::Bind(&RunStartWorkerCallback, callback, protect)); | 1325 base::Bind(&RunStartWorkerCallback, callback, protect)); |
| 1315 | 1326 |
| 1316 if (running_status() == STOPPED) | 1327 if (running_status() == EmbeddedWorkerStatus::STOPPED) |
| 1317 StartWorkerInternal(); | 1328 StartWorkerInternal(); |
| 1318 DCHECK(timeout_timer_.IsRunning()); | 1329 DCHECK(timeout_timer_.IsRunning()); |
| 1319 } | 1330 } |
| 1320 | 1331 |
| 1321 void ServiceWorkerVersion::StartWorkerInternal() { | 1332 void ServiceWorkerVersion::StartWorkerInternal() { |
| 1322 DCHECK_EQ(STOPPED, running_status()); | 1333 DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status()); |
| 1323 | 1334 |
| 1324 DCHECK(!metrics_); | 1335 DCHECK(!metrics_); |
| 1325 metrics_.reset(new Metrics(this)); | 1336 metrics_.reset(new Metrics(this)); |
| 1326 | 1337 |
| 1327 StartTimeoutTimer(); | 1338 StartTimeoutTimer(); |
| 1328 | 1339 |
| 1329 std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( | 1340 std::unique_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( |
| 1330 new EmbeddedWorkerMsg_StartWorker_Params()); | 1341 new EmbeddedWorkerMsg_StartWorker_Params()); |
| 1331 params->service_worker_version_id = version_id_; | 1342 params->service_worker_version_id = version_id_; |
| 1332 params->scope = scope_; | 1343 params->scope = scope_; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1378 void ServiceWorkerVersion::SetTimeoutTimerInterval(base::TimeDelta interval) { | 1389 void ServiceWorkerVersion::SetTimeoutTimerInterval(base::TimeDelta interval) { |
| 1379 DCHECK(timeout_timer_.IsRunning()); | 1390 DCHECK(timeout_timer_.IsRunning()); |
| 1380 if (timeout_timer_.GetCurrentDelay() != interval) { | 1391 if (timeout_timer_.GetCurrentDelay() != interval) { |
| 1381 timeout_timer_.Stop(); | 1392 timeout_timer_.Stop(); |
| 1382 timeout_timer_.Start(FROM_HERE, interval, this, | 1393 timeout_timer_.Start(FROM_HERE, interval, this, |
| 1383 &ServiceWorkerVersion::OnTimeoutTimer); | 1394 &ServiceWorkerVersion::OnTimeoutTimer); |
| 1384 } | 1395 } |
| 1385 } | 1396 } |
| 1386 | 1397 |
| 1387 void ServiceWorkerVersion::OnTimeoutTimer() { | 1398 void ServiceWorkerVersion::OnTimeoutTimer() { |
| 1388 DCHECK(running_status() == STARTING || running_status() == RUNNING || | 1399 DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || |
| 1389 running_status() == STOPPING) | 1400 running_status() == EmbeddedWorkerStatus::RUNNING || |
| 1390 << running_status(); | 1401 running_status() == EmbeddedWorkerStatus::STOPPING) |
| 1402 << static_cast<int>(running_status()); |
| 1391 | 1403 |
| 1392 if (!context_) | 1404 if (!context_) |
| 1393 return; | 1405 return; |
| 1394 | 1406 |
| 1395 MarkIfStale(); | 1407 MarkIfStale(); |
| 1396 | 1408 |
| 1397 // Stopping the worker hasn't finished within a certain period. | 1409 // Stopping the worker hasn't finished within a certain period. |
| 1398 if (GetTickDuration(stop_time_) > | 1410 if (GetTickDuration(stop_time_) > |
| 1399 base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds)) { | 1411 base::TimeDelta::FromSeconds(kStopWorkerTimeoutSeconds)) { |
| 1400 DCHECK_EQ(STOPPING, running_status()); | 1412 DCHECK_EQ(EmbeddedWorkerStatus::STOPPING, running_status()); |
| 1401 if (IsInstalled(status())) { | 1413 if (IsInstalled(status())) { |
| 1402 ServiceWorkerMetrics::RecordWorkerStopped( | 1414 ServiceWorkerMetrics::RecordWorkerStopped( |
| 1403 ServiceWorkerMetrics::StopStatus::TIMEOUT); | 1415 ServiceWorkerMetrics::StopStatus::TIMEOUT); |
| 1404 } | 1416 } |
| 1405 ReportError(SERVICE_WORKER_ERROR_TIMEOUT, "DETACH_STALLED_IN_STOPPING"); | 1417 ReportError(SERVICE_WORKER_ERROR_TIMEOUT, "DETACH_STALLED_IN_STOPPING"); |
| 1406 | 1418 |
| 1407 // Detach the worker. Remove |this| as a listener first; otherwise | 1419 // Detach the worker. Remove |this| as a listener first; otherwise |
| 1408 // OnStoppedInternal might try to restart before the new worker | 1420 // OnStoppedInternal might try to restart before the new worker |
| 1409 // is created. | 1421 // is created. |
| 1410 embedded_worker_->RemoveListener(this); | 1422 embedded_worker_->RemoveListener(this); |
| 1411 embedded_worker_->Detach(); | 1423 embedded_worker_->Detach(); |
| 1412 embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(); | 1424 embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(); |
| 1413 embedded_worker_->AddListener(this); | 1425 embedded_worker_->AddListener(this); |
| 1414 | 1426 |
| 1415 // Call OnStoppedInternal to fail callbacks and possibly restart. | 1427 // Call OnStoppedInternal to fail callbacks and possibly restart. |
| 1416 OnStoppedInternal(EmbeddedWorkerInstance::STOPPING); | 1428 OnStoppedInternal(EmbeddedWorkerStatus::STOPPING); |
| 1417 return; | 1429 return; |
| 1418 } | 1430 } |
| 1419 | 1431 |
| 1420 // Trigger update if worker is stale and we waited long enough for it to go | 1432 // Trigger update if worker is stale and we waited long enough for it to go |
| 1421 // idle. | 1433 // idle. |
| 1422 if (GetTickDuration(stale_time_) > | 1434 if (GetTickDuration(stale_time_) > |
| 1423 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)) { | 1435 base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)) { |
| 1424 ClearTick(&stale_time_); | 1436 ClearTick(&stale_time_); |
| 1425 if (!update_timer_.IsRunning()) | 1437 if (!update_timer_.IsRunning()) |
| 1426 ScheduleUpdate(); | 1438 ScheduleUpdate(); |
| 1427 } | 1439 } |
| 1428 | 1440 |
| 1429 // Starting a worker hasn't finished within a certain period. | 1441 // Starting a worker hasn't finished within a certain period. |
| 1430 const base::TimeDelta start_limit = | 1442 const base::TimeDelta start_limit = |
| 1431 IsInstalled(status()) | 1443 IsInstalled(status()) |
| 1432 ? base::TimeDelta::FromSeconds(kStartInstalledWorkerTimeoutSeconds) | 1444 ? base::TimeDelta::FromSeconds(kStartInstalledWorkerTimeoutSeconds) |
| 1433 : base::TimeDelta::FromMinutes(kStartNewWorkerTimeoutMinutes); | 1445 : base::TimeDelta::FromMinutes(kStartNewWorkerTimeoutMinutes); |
| 1434 if (GetTickDuration(start_time_) > start_limit) { | 1446 if (GetTickDuration(start_time_) > start_limit) { |
| 1435 DCHECK(running_status() == STARTING || running_status() == STOPPING) | 1447 DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || |
| 1436 << running_status(); | 1448 running_status() == EmbeddedWorkerStatus::STOPPING) |
| 1449 << static_cast<int>(running_status()); |
| 1437 scoped_refptr<ServiceWorkerVersion> protect(this); | 1450 scoped_refptr<ServiceWorkerVersion> protect(this); |
| 1438 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); | 1451 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_ERROR_TIMEOUT); |
| 1439 if (running_status() == STARTING) | 1452 if (running_status() == EmbeddedWorkerStatus::STARTING) |
| 1440 embedded_worker_->Stop(); | 1453 embedded_worker_->Stop(); |
| 1441 return; | 1454 return; |
| 1442 } | 1455 } |
| 1443 | 1456 |
| 1444 // Requests have not finished before their expiration. | 1457 // Requests have not finished before their expiration. |
| 1445 bool stop_for_timeout = false; | 1458 bool stop_for_timeout = false; |
| 1446 while (!requests_.empty()) { | 1459 while (!requests_.empty()) { |
| 1447 RequestInfo info = requests_.top(); | 1460 RequestInfo info = requests_.top(); |
| 1448 if (!RequestExpired(info.expiration)) | 1461 if (!RequestExpired(info.expiration)) |
| 1449 break; | 1462 break; |
| 1450 if (MaybeTimeOutRequest(info)) { | 1463 if (MaybeTimeOutRequest(info)) { |
| 1451 stop_for_timeout = | 1464 stop_for_timeout = |
| 1452 stop_for_timeout || info.timeout_behavior == KILL_ON_TIMEOUT; | 1465 stop_for_timeout || info.timeout_behavior == KILL_ON_TIMEOUT; |
| 1453 ServiceWorkerMetrics::RecordEventTimeout(info.event_type); | 1466 ServiceWorkerMetrics::RecordEventTimeout(info.event_type); |
| 1454 } | 1467 } |
| 1455 requests_.pop(); | 1468 requests_.pop(); |
| 1456 } | 1469 } |
| 1457 if (stop_for_timeout && running_status() != STOPPING) | 1470 if (stop_for_timeout && running_status() != EmbeddedWorkerStatus::STOPPING) |
| 1458 embedded_worker_->Stop(); | 1471 embedded_worker_->Stop(); |
| 1459 | 1472 |
| 1460 // For the timeouts below, there are no callbacks to timeout so there is | 1473 // For the timeouts below, there are no callbacks to timeout so there is |
| 1461 // nothing more to do if the worker is already stopping. | 1474 // nothing more to do if the worker is already stopping. |
| 1462 if (running_status() == STOPPING) | 1475 if (running_status() == EmbeddedWorkerStatus::STOPPING) |
| 1463 return; | 1476 return; |
| 1464 | 1477 |
| 1465 // The worker has been idle for longer than a certain period. | 1478 // The worker has been idle for longer than a certain period. |
| 1466 if (GetTickDuration(idle_time_) > | 1479 if (GetTickDuration(idle_time_) > |
| 1467 base::TimeDelta::FromSeconds(kIdleWorkerTimeoutSeconds)) { | 1480 base::TimeDelta::FromSeconds(kIdleWorkerTimeoutSeconds)) { |
| 1468 StopWorkerIfIdle(); | 1481 StopWorkerIfIdle(); |
| 1469 return; | 1482 return; |
| 1470 } | 1483 } |
| 1471 | 1484 |
| 1472 // Check ping status. | 1485 // Check ping status. |
| 1473 ping_controller_->CheckPingStatus(); | 1486 ping_controller_->CheckPingStatus(); |
| 1474 } | 1487 } |
| 1475 | 1488 |
| 1476 ServiceWorkerStatusCode ServiceWorkerVersion::PingWorker() { | 1489 ServiceWorkerStatusCode ServiceWorkerVersion::PingWorker() { |
| 1477 DCHECK(running_status() == STARTING || running_status() == RUNNING); | 1490 DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || |
| 1491 running_status() == EmbeddedWorkerStatus::RUNNING); |
| 1478 return embedded_worker_->SendMessage(ServiceWorkerMsg_Ping()); | 1492 return embedded_worker_->SendMessage(ServiceWorkerMsg_Ping()); |
| 1479 } | 1493 } |
| 1480 | 1494 |
| 1481 void ServiceWorkerVersion::OnPingTimeout() { | 1495 void ServiceWorkerVersion::OnPingTimeout() { |
| 1482 DCHECK(running_status() == STARTING || running_status() == RUNNING); | 1496 DCHECK(running_status() == EmbeddedWorkerStatus::STARTING || |
| 1497 running_status() == EmbeddedWorkerStatus::RUNNING); |
| 1483 // TODO(falken): Show a message to the developer that the SW was stopped due | 1498 // TODO(falken): Show a message to the developer that the SW was stopped due |
| 1484 // to timeout (crbug.com/457968). Also, change the error code to | 1499 // to timeout (crbug.com/457968). Also, change the error code to |
| 1485 // SERVICE_WORKER_ERROR_TIMEOUT. | 1500 // SERVICE_WORKER_ERROR_TIMEOUT. |
| 1486 StopWorkerIfIdle(); | 1501 StopWorkerIfIdle(); |
| 1487 } | 1502 } |
| 1488 | 1503 |
| 1489 void ServiceWorkerVersion::StopWorkerIfIdle() { | 1504 void ServiceWorkerVersion::StopWorkerIfIdle() { |
| 1490 if (HasInflightRequests() && !ping_controller_->IsTimedOut()) | 1505 if (HasInflightRequests() && !ping_controller_->IsTimedOut()) |
| 1491 return; | 1506 return; |
| 1492 if (running_status() == STOPPED || running_status() == STOPPING || | 1507 if (running_status() == EmbeddedWorkerStatus::STOPPED || |
| 1508 running_status() == EmbeddedWorkerStatus::STOPPING || |
| 1493 !stop_callbacks_.empty()) { | 1509 !stop_callbacks_.empty()) { |
| 1494 return; | 1510 return; |
| 1495 } | 1511 } |
| 1496 | 1512 |
| 1497 embedded_worker_->StopIfIdle(); | 1513 embedded_worker_->StopIfIdle(); |
| 1498 } | 1514 } |
| 1499 | 1515 |
| 1500 bool ServiceWorkerVersion::HasInflightRequests() const { | 1516 bool ServiceWorkerVersion::HasInflightRequests() const { |
| 1501 return !custom_requests_.IsEmpty() || !streaming_url_request_jobs_.empty(); | 1517 return !custom_requests_.IsEmpty() || !streaming_url_request_jobs_.empty(); |
| 1502 } | 1518 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1527 GetTickDuration(start_time), IsInstalled(prestart_status), | 1543 GetTickDuration(start_time), IsInstalled(prestart_status), |
| 1528 ServiceWorkerMetrics::GetStartSituation( | 1544 ServiceWorkerMetrics::GetStartSituation( |
| 1529 is_browser_startup_complete, embedded_worker_->is_new_process()), | 1545 is_browser_startup_complete, embedded_worker_->is_new_process()), |
| 1530 purpose); | 1546 purpose); |
| 1531 } | 1547 } |
| 1532 | 1548 |
| 1533 if (status != SERVICE_WORKER_ERROR_TIMEOUT) | 1549 if (status != SERVICE_WORKER_ERROR_TIMEOUT) |
| 1534 return; | 1550 return; |
| 1535 EmbeddedWorkerInstance::StartingPhase phase = | 1551 EmbeddedWorkerInstance::StartingPhase phase = |
| 1536 EmbeddedWorkerInstance::NOT_STARTING; | 1552 EmbeddedWorkerInstance::NOT_STARTING; |
| 1537 EmbeddedWorkerInstance::Status running_status = embedded_worker_->status(); | 1553 EmbeddedWorkerStatus running_status = embedded_worker_->status(); |
| 1538 // Build an artifical JavaScript exception to show in the ServiceWorker | 1554 // Build an artifical JavaScript exception to show in the ServiceWorker |
| 1539 // log for developers; it's not user-facing so it's not a localized resource. | 1555 // log for developers; it's not user-facing so it's not a localized resource. |
| 1540 std::string message = "ServiceWorker startup timed out. "; | 1556 std::string message = "ServiceWorker startup timed out. "; |
| 1541 if (running_status != EmbeddedWorkerInstance::STARTING) { | 1557 if (running_status != EmbeddedWorkerStatus::STARTING) { |
| 1542 message.append("The worker had unexpected status: "); | 1558 message.append("The worker had unexpected status: "); |
| 1543 message.append(EmbeddedWorkerInstance::StatusToString(running_status)); | 1559 message.append(EmbeddedWorkerInstance::StatusToString(running_status)); |
| 1544 } else { | 1560 } else { |
| 1545 phase = embedded_worker_->starting_phase(); | 1561 phase = embedded_worker_->starting_phase(); |
| 1546 message.append("The worker was in startup phase: "); | 1562 message.append("The worker was in startup phase: "); |
| 1547 message.append(EmbeddedWorkerInstance::StartingPhaseToString(phase)); | 1563 message.append(EmbeddedWorkerInstance::StartingPhaseToString(phase)); |
| 1548 } | 1564 } |
| 1549 message.append("."); | 1565 message.append("."); |
| 1550 OnReportException(base::UTF8ToUTF16(message), -1, -1, GURL()); | 1566 OnReportException(base::UTF8ToUTF16(message), -1, -1, GURL()); |
| 1551 DVLOG(1) << message; | 1567 DVLOG(1) << message; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1630 context_->UnprotectVersion(version_id_); | 1646 context_->UnprotectVersion(version_id_); |
| 1631 is_update_scheduled_ = false; | 1647 is_update_scheduled_ = false; |
| 1632 } | 1648 } |
| 1633 | 1649 |
| 1634 if (status != SERVICE_WORKER_OK || registration->active_version() != this) | 1650 if (status != SERVICE_WORKER_OK || registration->active_version() != this) |
| 1635 return; | 1651 return; |
| 1636 context_->UpdateServiceWorker(registration.get(), | 1652 context_->UpdateServiceWorker(registration.get(), |
| 1637 false /* force_bypass_cache */); | 1653 false /* force_bypass_cache */); |
| 1638 } | 1654 } |
| 1639 | 1655 |
| 1640 void ServiceWorkerVersion::OnStoppedInternal( | 1656 void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) { |
| 1641 EmbeddedWorkerInstance::Status old_status) { | 1657 DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status()); |
| 1642 DCHECK_EQ(STOPPED, running_status()); | |
| 1643 scoped_refptr<ServiceWorkerVersion> protect; | 1658 scoped_refptr<ServiceWorkerVersion> protect; |
| 1644 if (!in_dtor_) | 1659 if (!in_dtor_) |
| 1645 protect = this; | 1660 protect = this; |
| 1646 | 1661 |
| 1647 DCHECK(metrics_); | 1662 DCHECK(metrics_); |
| 1648 metrics_.reset(); | 1663 metrics_.reset(); |
| 1649 | 1664 |
| 1650 bool should_restart = !is_redundant() && !start_callbacks_.empty() && | 1665 bool should_restart = !is_redundant() && !start_callbacks_.empty() && |
| 1651 (old_status != EmbeddedWorkerInstance::STARTING) && | 1666 (old_status != EmbeddedWorkerStatus::STARTING) && |
| 1652 !in_dtor_ && !ping_controller_->IsTimedOut(); | 1667 !in_dtor_ && !ping_controller_->IsTimedOut(); |
| 1653 | 1668 |
| 1654 if (!stop_time_.is_null()) { | 1669 if (!stop_time_.is_null()) { |
| 1655 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::StopWorker", | 1670 TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::StopWorker", |
| 1656 stop_time_.ToInternalValue(), "Restart", | 1671 stop_time_.ToInternalValue(), "Restart", |
| 1657 should_restart); | 1672 should_restart); |
| 1658 ClearTick(&stop_time_); | 1673 ClearTick(&stop_time_); |
| 1659 } | 1674 } |
| 1660 StopTimeoutTimer(); | 1675 StopTimeoutTimer(); |
| 1661 | 1676 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1695 StartWorkerInternal(); | 1710 StartWorkerInternal(); |
| 1696 } | 1711 } |
| 1697 | 1712 |
| 1698 void ServiceWorkerVersion::OnMojoConnectionError(const char* service_name) { | 1713 void ServiceWorkerVersion::OnMojoConnectionError(const char* service_name) { |
| 1699 // Simply deleting the service will cause error callbacks to be called from | 1714 // Simply deleting the service will cause error callbacks to be called from |
| 1700 // the destructor of the MojoServiceWrapper instance. | 1715 // the destructor of the MojoServiceWrapper instance. |
| 1701 mojo_services_.erase(service_name); | 1716 mojo_services_.erase(service_name); |
| 1702 } | 1717 } |
| 1703 | 1718 |
| 1704 void ServiceWorkerVersion::OnBeginEvent() { | 1719 void ServiceWorkerVersion::OnBeginEvent() { |
| 1705 if (should_exclude_from_uma_ || running_status() != RUNNING || | 1720 if (should_exclude_from_uma_ || |
| 1721 running_status() != EmbeddedWorkerStatus::RUNNING || |
| 1706 idle_time_.is_null()) { | 1722 idle_time_.is_null()) { |
| 1707 return; | 1723 return; |
| 1708 } | 1724 } |
| 1709 ServiceWorkerMetrics::RecordTimeBetweenEvents(base::TimeTicks::Now() - | 1725 ServiceWorkerMetrics::RecordTimeBetweenEvents(base::TimeTicks::Now() - |
| 1710 idle_time_); | 1726 idle_time_); |
| 1711 } | 1727 } |
| 1712 | 1728 |
| 1713 } // namespace content | 1729 } // namespace content |
| OLD | NEW |