| 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/embedded_worker_instance.h" | 5 #include "content/browser/service_worker/embedded_worker_instance.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 status_ == EmbeddedWorkerStatus::STOPPED) | 435 status_ == EmbeddedWorkerStatus::STOPPED) |
| 436 << static_cast<int>(status_); | 436 << static_cast<int>(status_); |
| 437 devtools_proxy_.reset(); | 437 devtools_proxy_.reset(); |
| 438 if (registry_->GetWorker(embedded_worker_id_)) | 438 if (registry_->GetWorker(embedded_worker_id_)) |
| 439 registry_->RemoveWorker(process_id(), embedded_worker_id_); | 439 registry_->RemoveWorker(process_id(), embedded_worker_id_); |
| 440 process_handle_.reset(); | 440 process_handle_.reset(); |
| 441 } | 441 } |
| 442 | 442 |
| 443 void EmbeddedWorkerInstance::Start( | 443 void EmbeddedWorkerInstance::Start( |
| 444 std::unique_ptr<EmbeddedWorkerStartParams> params, | 444 std::unique_ptr<EmbeddedWorkerStartParams> params, |
| 445 ProviderInfoGetter provider_info_getter, | |
| 446 mojom::ServiceWorkerEventDispatcherRequest dispatcher_request, | 445 mojom::ServiceWorkerEventDispatcherRequest dispatcher_request, |
| 447 const StatusCallback& callback) { | 446 const StatusCallback& callback) { |
| 448 restart_count_++; | 447 restart_count_++; |
| 449 if (!context_) { | 448 if (!context_) { |
| 450 callback.Run(SERVICE_WORKER_ERROR_ABORT); | 449 callback.Run(SERVICE_WORKER_ERROR_ABORT); |
| 451 // |this| may be destroyed by the callback. | 450 // |this| may be destroyed by the callback. |
| 452 return; | 451 return; |
| 453 } | 452 } |
| 454 DCHECK(status_ == EmbeddedWorkerStatus::STOPPED); | 453 DCHECK(status_ == EmbeddedWorkerStatus::STOPPED); |
| 455 | 454 |
| 456 DCHECK(!params->pause_after_download || !params->is_installed); | 455 DCHECK(!params->pause_after_download || !params->is_installed); |
| 457 DCHECK_NE(kInvalidServiceWorkerVersionId, params->service_worker_version_id); | 456 DCHECK_NE(kInvalidServiceWorkerVersionId, params->service_worker_version_id); |
| 458 step_time_ = base::TimeTicks::Now(); | 457 step_time_ = base::TimeTicks::Now(); |
| 459 status_ = EmbeddedWorkerStatus::STARTING; | 458 status_ = EmbeddedWorkerStatus::STARTING; |
| 460 starting_phase_ = ALLOCATING_PROCESS; | 459 starting_phase_ = ALLOCATING_PROCESS; |
| 461 network_accessed_for_script_ = false; | 460 network_accessed_for_script_ = false; |
| 462 provider_info_getter_ = std::move(provider_info_getter); | |
| 463 | |
| 464 for (auto& observer : listener_list_) | 461 for (auto& observer : listener_list_) |
| 465 observer.OnStarting(); | 462 observer.OnStarting(); |
| 466 | 463 |
| 467 params->embedded_worker_id = embedded_worker_id_; | 464 params->embedded_worker_id = embedded_worker_id_; |
| 468 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; | 465 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; |
| 469 params->wait_for_debugger = false; | 466 params->wait_for_debugger = false; |
| 470 params->settings.v8_cache_options = GetV8CacheOptions(); | 467 params->settings.v8_cache_options = GetV8CacheOptions(); |
| 471 | 468 |
| 472 mojom::EmbeddedWorkerInstanceClientRequest request = | 469 mojom::EmbeddedWorkerInstanceClientRequest request = |
| 473 mojo::MakeRequest(&client_); | 470 mojo::MakeRequest(&client_); |
| 474 client_.set_connection_error_handler( | 471 client_.set_connection_error_handler( |
| 475 base::Bind(&CallDetach, base::Unretained(this))); | 472 base::Bind(&CallDetach, base::Unretained(this))); |
| 473 |
| 476 pending_dispatcher_request_ = std::move(dispatcher_request); | 474 pending_dispatcher_request_ = std::move(dispatcher_request); |
| 477 | 475 |
| 478 inflight_start_task_.reset( | 476 inflight_start_task_.reset( |
| 479 new StartTask(this, params->script_url, std::move(request))); | 477 new StartTask(this, params->script_url, std::move(request))); |
| 480 inflight_start_task_->Start(std::move(params), callback); | 478 inflight_start_task_->Start(std::move(params), callback); |
| 481 } | 479 } |
| 482 | 480 |
| 483 bool EmbeddedWorkerInstance::Stop() { | 481 bool EmbeddedWorkerInstance::Stop() { |
| 484 DCHECK(status_ == EmbeddedWorkerStatus::STARTING || | 482 DCHECK(status_ == EmbeddedWorkerStatus::STARTING || |
| 485 status_ == EmbeddedWorkerStatus::RUNNING) | 483 status_ == EmbeddedWorkerStatus::RUNNING) |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker( | 588 ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker( |
| 591 std::unique_ptr<EmbeddedWorkerStartParams> params) { | 589 std::unique_ptr<EmbeddedWorkerStartParams> params) { |
| 592 if (!context_) | 590 if (!context_) |
| 593 return SERVICE_WORKER_ERROR_ABORT; | 591 return SERVICE_WORKER_ERROR_ABORT; |
| 594 DCHECK(pending_dispatcher_request_.is_pending()); | 592 DCHECK(pending_dispatcher_request_.is_pending()); |
| 595 | 593 |
| 596 DCHECK(!instance_host_binding_.is_bound()); | 594 DCHECK(!instance_host_binding_.is_bound()); |
| 597 mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info; | 595 mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo host_ptr_info; |
| 598 instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info)); | 596 instance_host_binding_.Bind(mojo::MakeRequest(&host_ptr_info)); |
| 599 | 597 |
| 600 mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info = | 598 DCHECK(pending_dispatcher_request_.is_pending()); |
| 601 std::move(provider_info_getter_).Run(process_id()); | |
| 602 | |
| 603 client_->StartWorker(*params, std::move(pending_dispatcher_request_), | 599 client_->StartWorker(*params, std::move(pending_dispatcher_request_), |
| 604 std::move(host_ptr_info), std::move(provider_info)); | 600 std::move(host_ptr_info)); |
| 605 registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); | 601 registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); |
| 606 | |
| 607 OnStartWorkerMessageSent(); | 602 OnStartWorkerMessageSent(); |
| 608 // Once the start worker message is received, renderer side will prepare a | 603 // Once the start worker message is received, renderer side will prepare a |
| 609 // shadow page for getting worker script. | 604 // shadow page for getting worker script. |
| 610 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "PREPARING_SCRIPT_LOAD", | 605 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "PREPARING_SCRIPT_LOAD", |
| 611 this); | 606 this); |
| 612 return SERVICE_WORKER_OK; | 607 return SERVICE_WORKER_OK; |
| 613 } | 608 } |
| 614 | 609 |
| 615 void EmbeddedWorkerInstance::OnStartWorkerMessageSent() { | 610 void EmbeddedWorkerInstance::OnStartWorkerMessageSent() { |
| 616 if (!step_time_.is_null()) { | 611 if (!step_time_.is_null()) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 void EmbeddedWorkerInstance::OnWorkerVersionInstalled() { | 695 void EmbeddedWorkerInstance::OnWorkerVersionInstalled() { |
| 701 if (devtools_proxy_) | 696 if (devtools_proxy_) |
| 702 devtools_proxy_->NotifyWorkerVersionInstalled(); | 697 devtools_proxy_->NotifyWorkerVersionInstalled(); |
| 703 } | 698 } |
| 704 | 699 |
| 705 void EmbeddedWorkerInstance::OnWorkerVersionDoomed() { | 700 void EmbeddedWorkerInstance::OnWorkerVersionDoomed() { |
| 706 if (devtools_proxy_) | 701 if (devtools_proxy_) |
| 707 devtools_proxy_->NotifyWorkerVersionDoomed(); | 702 devtools_proxy_->NotifyWorkerVersionDoomed(); |
| 708 } | 703 } |
| 709 | 704 |
| 710 void EmbeddedWorkerInstance::OnThreadStarted(int thread_id) { | 705 void EmbeddedWorkerInstance::OnThreadStarted(int thread_id, int provider_id) { |
| 711 if (!context_ || !inflight_start_task_) | 706 if (!context_ || !inflight_start_task_) |
| 712 return; | 707 return; |
| 713 | 708 |
| 709 ServiceWorkerProviderHost* provider_host = |
| 710 context_->GetProviderHost(process_id(), provider_id); |
| 711 if (!provider_host) { |
| 712 bad_message::ReceivedBadMessage( |
| 713 process_id(), bad_message::SWDH_WORKER_SCRIPT_LOAD_NO_HOST); |
| 714 return; |
| 715 } |
| 716 |
| 717 provider_host->SetReadyToSendMessagesToWorker(thread_id); |
| 718 |
| 714 TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "LAUNCHING_WORKER_THREAD", | 719 TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "LAUNCHING_WORKER_THREAD", |
| 715 this); | 720 this); |
| 716 // Renderer side has started to evaluate the loaded worker script. | 721 // Renderer side has started to evaluate the loaded worker script. |
| 717 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATING_SCRIPT", this); | 722 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATING_SCRIPT", this); |
| 718 starting_phase_ = THREAD_STARTED; | 723 starting_phase_ = THREAD_STARTED; |
| 719 if (!step_time_.is_null()) { | 724 if (!step_time_.is_null()) { |
| 720 base::TimeDelta duration = UpdateStepTime(); | 725 base::TimeDelta duration = UpdateStepTime(); |
| 721 if (inflight_start_task_->is_installed()) | 726 if (inflight_start_task_->is_installed()) |
| 722 ServiceWorkerMetrics::RecordTimeToStartThread(duration, start_situation_); | 727 ServiceWorkerMetrics::RecordTimeToStartThread(duration, start_situation_); |
| 723 } | 728 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 } | 805 } |
| 801 | 806 |
| 802 void EmbeddedWorkerInstance::OnDetached() { | 807 void EmbeddedWorkerInstance::OnDetached() { |
| 803 EmbeddedWorkerStatus old_status = status_; | 808 EmbeddedWorkerStatus old_status = status_; |
| 804 ReleaseProcess(); | 809 ReleaseProcess(); |
| 805 for (auto& observer : listener_list_) | 810 for (auto& observer : listener_list_) |
| 806 observer.OnDetached(old_status); | 811 observer.OnDetached(old_status); |
| 807 } | 812 } |
| 808 | 813 |
| 809 void EmbeddedWorkerInstance::Detach() { | 814 void EmbeddedWorkerInstance::Detach() { |
| 810 if (status() == EmbeddedWorkerStatus::STOPPED) | |
| 811 return; | |
| 812 registry_->DetachWorker(process_id(), embedded_worker_id()); | 815 registry_->DetachWorker(process_id(), embedded_worker_id()); |
| 813 OnDetached(); | 816 OnDetached(); |
| 814 } | 817 } |
| 815 | 818 |
| 816 base::WeakPtr<EmbeddedWorkerInstance> EmbeddedWorkerInstance::AsWeakPtr() { | 819 base::WeakPtr<EmbeddedWorkerInstance> EmbeddedWorkerInstance::AsWeakPtr() { |
| 817 return weak_factory_.GetWeakPtr(); | 820 return weak_factory_.GetWeakPtr(); |
| 818 } | 821 } |
| 819 | 822 |
| 820 bool EmbeddedWorkerInstance::OnMessageReceived(const IPC::Message& message) { | 823 bool EmbeddedWorkerInstance::OnMessageReceived(const IPC::Message& message) { |
| 821 for (auto& listener : listener_list_) { | 824 for (auto& listener : listener_list_) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "SCRIPT_DOWNLOADING", | 886 TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "SCRIPT_DOWNLOADING", |
| 884 this); | 887 this); |
| 885 starting_phase_ = SCRIPT_DOWNLOADING; | 888 starting_phase_ = SCRIPT_DOWNLOADING; |
| 886 network_accessed_for_script_ = true; | 889 network_accessed_for_script_ = true; |
| 887 } | 890 } |
| 888 | 891 |
| 889 void EmbeddedWorkerInstance::ReleaseProcess() { | 892 void EmbeddedWorkerInstance::ReleaseProcess() { |
| 890 // Abort an inflight start task. | 893 // Abort an inflight start task. |
| 891 inflight_start_task_.reset(); | 894 inflight_start_task_.reset(); |
| 892 | 895 |
| 896 client_.reset(); |
| 893 instance_host_binding_.Close(); | 897 instance_host_binding_.Close(); |
| 894 devtools_proxy_.reset(); | 898 devtools_proxy_.reset(); |
| 895 process_handle_.reset(); | 899 process_handle_.reset(); |
| 896 status_ = EmbeddedWorkerStatus::STOPPED; | 900 status_ = EmbeddedWorkerStatus::STOPPED; |
| 897 starting_phase_ = NOT_STARTING; | 901 starting_phase_ = NOT_STARTING; |
| 898 thread_id_ = kInvalidEmbeddedWorkerThreadId; | 902 thread_id_ = kInvalidEmbeddedWorkerThreadId; |
| 899 } | 903 } |
| 900 | 904 |
| 901 void EmbeddedWorkerInstance::OnStartFailed(const StatusCallback& callback, | 905 void EmbeddedWorkerInstance::OnStartFailed(const StatusCallback& callback, |
| 902 ServiceWorkerStatusCode status) { | 906 ServiceWorkerStatusCode status) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 case SCRIPT_READ_FINISHED: | 973 case SCRIPT_READ_FINISHED: |
| 970 return "Script read finished"; | 974 return "Script read finished"; |
| 971 case STARTING_PHASE_MAX_VALUE: | 975 case STARTING_PHASE_MAX_VALUE: |
| 972 NOTREACHED(); | 976 NOTREACHED(); |
| 973 } | 977 } |
| 974 NOTREACHED() << phase; | 978 NOTREACHED() << phase; |
| 975 return std::string(); | 979 return std::string(); |
| 976 } | 980 } |
| 977 | 981 |
| 978 } // namespace content | 982 } // namespace content |
| OLD | NEW |