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 |