| 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" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/threading/non_thread_safe.h" | 13 #include "base/threading/non_thread_safe.h" |
| 14 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
| 15 #include "content/browser/devtools/service_worker_devtools_manager.h" | 15 #include "content/browser/devtools/service_worker_devtools_manager.h" |
| 16 #include "content/browser/service_worker/embedded_worker_registry.h" | 16 #include "content/browser/service_worker/embedded_worker_registry.h" |
| 17 #include "content/browser/service_worker/embedded_worker_status.h" | 17 #include "content/browser/service_worker/embedded_worker_status.h" |
| 18 #include "content/browser/service_worker/service_worker_context_core.h" | 18 #include "content/browser/service_worker/service_worker_context_core.h" |
| 19 #include "content/common/content_switches_internal.h" | 19 #include "content/common/content_switches_internal.h" |
| 20 #include "content/common/service_worker/embedded_worker_messages.h" | 20 #include "content/common/service_worker/embedded_worker_messages.h" |
| 21 #include "content/common/service_worker/embedded_worker_settings.h" | 21 #include "content/common/service_worker/embedded_worker_settings.h" |
| 22 #include "content/common/service_worker/embedded_worker_setup.mojom.h" | |
| 23 #include "content/common/service_worker/embedded_worker_start_params.h" | 22 #include "content/common/service_worker/embedded_worker_start_params.h" |
| 24 #include "content/common/service_worker/service_worker_types.h" | 23 #include "content/common/service_worker/service_worker_types.h" |
| 25 #include "content/common/service_worker/service_worker_utils.h" | 24 #include "content/common/service_worker/service_worker_utils.h" |
| 26 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 27 #include "content/public/browser/content_browser_client.h" | 26 #include "content/public/browser/content_browser_client.h" |
| 28 #include "content/public/browser/render_process_host.h" | 27 #include "content/public/browser/render_process_host.h" |
| 29 #include "content/public/common/child_process_host.h" | 28 #include "content/public/common/child_process_host.h" |
| 30 #include "content/public/common/content_switches.h" | 29 #include "content/public/common/content_switches.h" |
| 31 #include "ipc/ipc_message.h" | 30 #include "ipc/ipc_message.h" |
| 32 #include "url/gurl.h" | 31 #include "url/gurl.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 is_installed); | 95 is_installed); |
| 97 if (request.is_pending()) | 96 if (request.is_pending()) |
| 98 rph->GetRemoteInterfaces()->GetInterface(std::move(request)); | 97 rph->GetRemoteInterfaces()->GetInterface(std::move(request)); |
| 99 } | 98 } |
| 100 BrowserThread::PostTask( | 99 BrowserThread::PostTask( |
| 101 BrowserThread::IO, | 100 BrowserThread::IO, |
| 102 FROM_HERE, | 101 FROM_HERE, |
| 103 base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger)); | 102 base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger)); |
| 104 } | 103 } |
| 105 | 104 |
| 106 void SetupEventDispatcherOnUIThread( | |
| 107 int process_id, | |
| 108 int thread_id, | |
| 109 mojom::ServiceWorkerEventDispatcherRequest request) { | |
| 110 DCHECK(!ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()); | |
| 111 RenderProcessHost* rph = RenderProcessHost::FromID(process_id); | |
| 112 // |rph| or its InterfaceProvider may be NULL in unit tests. | |
| 113 if (!rph || !rph->GetRemoteInterfaces()) | |
| 114 return; | |
| 115 mojom::EmbeddedWorkerSetupPtr setup; | |
| 116 rph->GetRemoteInterfaces()->GetInterface(&setup); | |
| 117 setup->AttachServiceWorkerEventDispatcher(thread_id, std::move(request)); | |
| 118 } | |
| 119 | |
| 120 void CallDetach(EmbeddedWorkerInstance* instance) { | 105 void CallDetach(EmbeddedWorkerInstance* instance) { |
| 121 // This could be called on the UI thread if |client_| still be valid when the | 106 // This could be called on the UI thread if |client_| still be valid when the |
| 122 // message loop on the UI thread gets destructed. | 107 // message loop on the UI thread gets destructed. |
| 123 // TODO(shimazu): Remove this after https://crbug.com/604762 is fixed | 108 // TODO(shimazu): Remove this after https://crbug.com/604762 is fixed |
| 124 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 109 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 125 DCHECK(ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()); | 110 DCHECK(ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()); |
| 126 return; | 111 return; |
| 127 } | 112 } |
| 128 instance->Detach(); | 113 instance->Detach(); |
| 129 } | 114 } |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 "EmbeddedWorkerInstance::Start", this, | 379 "EmbeddedWorkerInstance::Start", this, |
| 395 "OnSetupOnUICompleted"); | 380 "OnSetupOnUICompleted"); |
| 396 | 381 |
| 397 // Notify the instance that it is registered to the devtools manager. | 382 // Notify the instance that it is registered to the devtools manager. |
| 398 instance_->OnRegisteredToDevToolsManager( | 383 instance_->OnRegisteredToDevToolsManager( |
| 399 is_new_process, worker_devtools_agent_route_id, wait_for_debugger); | 384 is_new_process, worker_devtools_agent_route_id, wait_for_debugger); |
| 400 | 385 |
| 401 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; | 386 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; |
| 402 params->wait_for_debugger = wait_for_debugger; | 387 params->wait_for_debugger = wait_for_debugger; |
| 403 | 388 |
| 404 if (ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()) | 389 ServiceWorkerStatusCode status = |
| 405 SendMojoStartWorker(std::move(params)); | 390 instance_->SendStartWorker(std::move(params)); |
| 406 else | |
| 407 SendStartWorker(std::move(params)); | |
| 408 } | |
| 409 | |
| 410 void SendStartWorker(std::unique_ptr<EmbeddedWorkerStartParams> params) { | |
| 411 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 412 ServiceWorkerStatusCode status = instance_->registry_->SendStartWorker( | |
| 413 std::move(params), instance_->process_id()); | |
| 414 TRACE_EVENT_ASYNC_STEP_PAST1( | |
| 415 "ServiceWorker", "EmbeddedWorkerInstance::Start", this, | |
| 416 "SendStartWorker", "Status", ServiceWorkerStatusToString(status)); | |
| 417 if (status != SERVICE_WORKER_OK) { | 391 if (status != SERVICE_WORKER_OK) { |
| 418 StatusCallback callback = start_callback_; | 392 StatusCallback callback = start_callback_; |
| 419 start_callback_.Reset(); | 393 start_callback_.Reset(); |
| 420 instance_->OnStartFailed(callback, status); | 394 instance_->OnStartFailed(callback, status); |
| 421 // |this| may be destroyed. | 395 // |this| may be destroyed. |
| 422 return; | |
| 423 } | |
| 424 instance_->OnStartWorkerMessageSent(); | |
| 425 | |
| 426 // |start_callback_| will be called via RunStartCallback() when the script | |
| 427 // is evaluated. | |
| 428 } | |
| 429 | |
| 430 void SendMojoStartWorker(std::unique_ptr<EmbeddedWorkerStartParams> params) { | |
| 431 ServiceWorkerStatusCode status = | |
| 432 instance_->SendMojoStartWorker(std::move(params)); | |
| 433 if (status != SERVICE_WORKER_OK) { | |
| 434 StatusCallback callback = start_callback_; | |
| 435 start_callback_.Reset(); | |
| 436 instance_->OnStartFailed(callback, status); | |
| 437 // |this| may be destroyed. | |
| 438 return; | |
| 439 } | 396 } |
| 440 } | 397 } |
| 441 | 398 |
| 442 // |instance_| must outlive |this|. | 399 // |instance_| must outlive |this|. |
| 443 EmbeddedWorkerInstance* instance_; | 400 EmbeddedWorkerInstance* instance_; |
| 444 | 401 |
| 445 // Ownership is transferred by base::Passed() to a task after process | 402 // Ownership is transferred by base::Passed() to a task after process |
| 446 // allocation. | 403 // allocation. |
| 447 mojom::EmbeddedWorkerInstanceClientRequest request_; | 404 mojom::EmbeddedWorkerInstanceClientRequest request_; |
| 448 | 405 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 starting_phase_ = ALLOCATING_PROCESS; | 449 starting_phase_ = ALLOCATING_PROCESS; |
| 493 network_accessed_for_script_ = false; | 450 network_accessed_for_script_ = false; |
| 494 for (auto& observer : listener_list_) | 451 for (auto& observer : listener_list_) |
| 495 observer.OnStarting(); | 452 observer.OnStarting(); |
| 496 | 453 |
| 497 params->embedded_worker_id = embedded_worker_id_; | 454 params->embedded_worker_id = embedded_worker_id_; |
| 498 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; | 455 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; |
| 499 params->wait_for_debugger = false; | 456 params->wait_for_debugger = false; |
| 500 params->settings.v8_cache_options = GetV8CacheOptions(); | 457 params->settings.v8_cache_options = GetV8CacheOptions(); |
| 501 | 458 |
| 502 mojom::EmbeddedWorkerInstanceClientRequest request; | 459 mojom::EmbeddedWorkerInstanceClientRequest request = |
| 503 if (ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()) { | 460 mojo::MakeRequest(&client_); |
| 504 request = mojo::MakeRequest(&client_); | 461 client_.set_connection_error_handler( |
| 505 client_.set_connection_error_handler( | 462 base::Bind(&CallDetach, base::Unretained(this))); |
| 506 base::Bind(&CallDetach, base::Unretained(this))); | |
| 507 } | |
| 508 | 463 |
| 509 pending_dispatcher_request_ = std::move(dispatcher_request); | 464 pending_dispatcher_request_ = std::move(dispatcher_request); |
| 510 | 465 |
| 511 inflight_start_task_.reset( | 466 inflight_start_task_.reset( |
| 512 new StartTask(this, params->script_url, std::move(request))); | 467 new StartTask(this, params->script_url, std::move(request))); |
| 513 inflight_start_task_->Start(std::move(params), callback); | 468 inflight_start_task_->Start(std::move(params), callback); |
| 514 } | 469 } |
| 515 | 470 |
| 516 bool EmbeddedWorkerInstance::Stop() { | 471 bool EmbeddedWorkerInstance::Stop() { |
| 517 DCHECK(status_ == EmbeddedWorkerStatus::STARTING || | 472 DCHECK(status_ == EmbeddedWorkerStatus::STARTING || |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 } | 583 } |
| 629 if (wait_for_debugger) { | 584 if (wait_for_debugger) { |
| 630 // We don't measure the start time when wait_for_debugger flag is set. So | 585 // We don't measure the start time when wait_for_debugger flag is set. So |
| 631 // we set the NULL time here. | 586 // we set the NULL time here. |
| 632 step_time_ = base::TimeTicks(); | 587 step_time_ = base::TimeTicks(); |
| 633 } | 588 } |
| 634 for (auto& observer : listener_list_) | 589 for (auto& observer : listener_list_) |
| 635 observer.OnRegisteredToDevToolsManager(); | 590 observer.OnRegisteredToDevToolsManager(); |
| 636 } | 591 } |
| 637 | 592 |
| 638 ServiceWorkerStatusCode EmbeddedWorkerInstance::SendMojoStartWorker( | 593 ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker( |
| 639 std::unique_ptr<EmbeddedWorkerStartParams> params) { | 594 std::unique_ptr<EmbeddedWorkerStartParams> params) { |
| 640 if (!context_) | 595 if (!context_) |
| 641 return SERVICE_WORKER_ERROR_ABORT; | 596 return SERVICE_WORKER_ERROR_ABORT; |
| 642 DCHECK(pending_dispatcher_request_.is_pending()); | 597 DCHECK(pending_dispatcher_request_.is_pending()); |
| 643 client_->StartWorker(*params, std::move(pending_dispatcher_request_)); | 598 client_->StartWorker(*params, std::move(pending_dispatcher_request_)); |
| 644 registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); | 599 registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); |
| 645 TRACE_EVENT_ASYNC_STEP_PAST1("ServiceWorker", "EmbeddedWorkerInstance::Start", | 600 TRACE_EVENT_ASYNC_STEP_PAST0("ServiceWorker", "EmbeddedWorkerInstance::Start", |
| 646 this, "SendStartWorker", "Status", "mojo"); | 601 this, "SendStartWorker"); |
| 647 OnStartWorkerMessageSent(); | 602 OnStartWorkerMessageSent(); |
| 648 return SERVICE_WORKER_OK; | 603 return SERVICE_WORKER_OK; |
| 649 } | 604 } |
| 650 | 605 |
| 651 void EmbeddedWorkerInstance::OnStartWorkerMessageSent() { | 606 void EmbeddedWorkerInstance::OnStartWorkerMessageSent() { |
| 652 if (!step_time_.is_null()) { | 607 if (!step_time_.is_null()) { |
| 653 base::TimeDelta duration = UpdateStepTime(); | 608 base::TimeDelta duration = UpdateStepTime(); |
| 654 if (inflight_start_task_->is_installed()) { | 609 if (inflight_start_task_->is_installed()) { |
| 655 ServiceWorkerMetrics::RecordTimeToSendStartWorker(duration, | 610 ServiceWorkerMetrics::RecordTimeToSendStartWorker(duration, |
| 656 start_situation_); | 611 start_situation_); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 starting_phase_ = THREAD_STARTED; | 691 starting_phase_ = THREAD_STARTED; |
| 737 if (!step_time_.is_null()) { | 692 if (!step_time_.is_null()) { |
| 738 base::TimeDelta duration = UpdateStepTime(); | 693 base::TimeDelta duration = UpdateStepTime(); |
| 739 if (inflight_start_task_->is_installed()) | 694 if (inflight_start_task_->is_installed()) |
| 740 ServiceWorkerMetrics::RecordTimeToStartThread(duration, start_situation_); | 695 ServiceWorkerMetrics::RecordTimeToStartThread(duration, start_situation_); |
| 741 } | 696 } |
| 742 | 697 |
| 743 thread_id_ = thread_id; | 698 thread_id_ = thread_id; |
| 744 for (auto& observer : listener_list_) | 699 for (auto& observer : listener_list_) |
| 745 observer.OnThreadStarted(); | 700 observer.OnThreadStarted(); |
| 746 | |
| 747 // The pending request is sent at StartWorker if mojo for the service worker | |
| 748 // is enabled. | |
| 749 if (!ServiceWorkerUtils::IsMojoForServiceWorkerEnabled()) { | |
| 750 DCHECK(pending_dispatcher_request_.is_pending()); | |
| 751 BrowserThread::PostTask( | |
| 752 BrowserThread::UI, FROM_HERE, | |
| 753 base::Bind(SetupEventDispatcherOnUIThread, process_id(), thread_id_, | |
| 754 base::Passed(&pending_dispatcher_request_))); | |
| 755 } | |
| 756 } | 701 } |
| 757 | 702 |
| 758 void EmbeddedWorkerInstance::OnScriptLoadFailed() { | 703 void EmbeddedWorkerInstance::OnScriptLoadFailed() { |
| 759 if (!inflight_start_task_) | 704 if (!inflight_start_task_) |
| 760 return; | 705 return; |
| 761 TRACE_EVENT_ASYNC_STEP_PAST0("ServiceWorker", "EmbeddedWorkerInstance::Start", | 706 TRACE_EVENT_ASYNC_STEP_PAST0("ServiceWorker", "EmbeddedWorkerInstance::Start", |
| 762 inflight_start_task_.get(), | 707 inflight_start_task_.get(), |
| 763 "OnScriptLoadFailed"); | 708 "OnScriptLoadFailed"); |
| 764 for (auto& observer : listener_list_) | 709 for (auto& observer : listener_list_) |
| 765 observer.OnScriptLoadFailed(); | 710 observer.OnScriptLoadFailed(); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 case SCRIPT_READ_FINISHED: | 918 case SCRIPT_READ_FINISHED: |
| 974 return "Script read finished"; | 919 return "Script read finished"; |
| 975 case STARTING_PHASE_MAX_VALUE: | 920 case STARTING_PHASE_MAX_VALUE: |
| 976 NOTREACHED(); | 921 NOTREACHED(); |
| 977 } | 922 } |
| 978 NOTREACHED() << phase; | 923 NOTREACHED() << phase; |
| 979 return std::string(); | 924 return std::string(); |
| 980 } | 925 } |
| 981 | 926 |
| 982 } // namespace content | 927 } // namespace content |
| OLD | NEW |