| Index: content/renderer/service_worker/embedded_worker_instance_client_impl.cc
 | 
| diff --git a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
 | 
| index 726595e4abddd697b51c80e3e8647c3ef60b641e..7de9b338402e5fce10715075263a612ecf70086e 100644
 | 
| --- a/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
 | 
| +++ b/content/renderer/service_worker/embedded_worker_instance_client_impl.cc
 | 
| @@ -7,6 +7,7 @@
 | 
|  #include <memory>
 | 
|  
 | 
|  #include "base/memory/ptr_util.h"
 | 
| +#include "base/metrics/histogram_macros.h"
 | 
|  #include "base/strings/utf_string_conversions.h"
 | 
|  #include "content/child/scoped_child_process_reference.h"
 | 
|  #include "content/common/service_worker/embedded_worker_messages.h"
 | 
| @@ -18,64 +19,63 @@
 | 
|  
 | 
|  namespace content {
 | 
|  
 | 
| +EmbeddedWorkerInstanceClientImpl::WorkerWrapper::WorkerWrapper(
 | 
| +    blink::WebEmbeddedWorker* worker,
 | 
| +    int devtools_agent_route_id)
 | 
| +    : worker_(worker),
 | 
| +      devtools_agent_(base::MakeUnique<EmbeddedWorkerDevToolsAgent>(
 | 
| +          worker,
 | 
| +          devtools_agent_route_id)) {}
 | 
| +
 | 
| +EmbeddedWorkerInstanceClientImpl::WorkerWrapper::~WorkerWrapper() = default;
 | 
| +
 | 
|  // static
 | 
|  void EmbeddedWorkerInstanceClientImpl::Create(
 | 
| -    EmbeddedWorkerDispatcher* dispatcher,
 | 
|      mojo::InterfaceRequest<mojom::EmbeddedWorkerInstanceClient> request) {
 | 
|    // This won't be leaked because the lifetime will be managed internally.
 | 
| -  new EmbeddedWorkerInstanceClientImpl(dispatcher, std::move(request));
 | 
| +  new EmbeddedWorkerInstanceClientImpl(std::move(request));
 | 
|  }
 | 
|  
 | 
| -void EmbeddedWorkerInstanceClientImpl::StopWorkerCompleted() {
 | 
| -  DCHECK(embedded_worker_id_);
 | 
| -  DCHECK(stop_callback_);
 | 
| +void EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed() {
 | 
| +  DCHECK(wrapper_);
 | 
|    TRACE_EVENT0("ServiceWorker",
 | 
| -               "EmbeddedWorkerInstanceClientImpl::StopWorkerCompleted");
 | 
| -  // TODO(falken): The signals to the browser should be in the order:
 | 
| -  // (1) WorkerStopped (via stop_callback_)
 | 
| -  // (2) ProviderDestroyed (via UnregisterWorker destroying
 | 
| -  //     WebEmbeddedWorkerImpl)
 | 
| -  // But this ordering is currently not guaranteed since the Mojo pipes are
 | 
| -  // different. https://crbug.com/676526
 | 
| -  stop_callback_.Run();
 | 
| -  stop_callback_.Reset();
 | 
| -  dispatcher_->UnregisterWorker(embedded_worker_id_.value());
 | 
| -  embedded_worker_id_.reset();
 | 
| -  wrapper_ = nullptr;
 | 
| +               "EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed");
 | 
| +
 | 
| +  if (stop_worker_time_) {
 | 
| +    UMA_HISTOGRAM_MEDIUM_TIMES(
 | 
| +        "ServiceWorker.TerminateThread.Time",
 | 
| +        base::TimeTicks::Now() - stop_worker_time_.value());
 | 
| +    stop_worker_time_.reset();
 | 
| +  }
 | 
| +  wrapper_.reset();
 | 
|  }
 | 
|  
 | 
|  void EmbeddedWorkerInstanceClientImpl::StartWorker(
 | 
|      const EmbeddedWorkerStartParams& params,
 | 
| -    mojom::ServiceWorkerEventDispatcherRequest dispatcher_request) {
 | 
| +    mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
 | 
| +    mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host) {
 | 
|    DCHECK(ChildThreadImpl::current());
 | 
|    DCHECK(!wrapper_);
 | 
| -  DCHECK(!embedded_worker_id_);
 | 
| +  DCHECK(!stop_worker_time_.has_value());
 | 
|    TRACE_EVENT0("ServiceWorker",
 | 
|                 "EmbeddedWorkerInstanceClientImpl::StartWorker");
 | 
| -  embedded_worker_id_ = params.embedded_worker_id;
 | 
| -
 | 
| -  std::unique_ptr<EmbeddedWorkerDispatcher::WorkerWrapper> wrapper =
 | 
| -      dispatcher_->StartWorkerContext(
 | 
| -          params,
 | 
| -          base::MakeUnique<ServiceWorkerContextClient>(
 | 
| -              params.embedded_worker_id, params.service_worker_version_id,
 | 
| -              params.scope, params.script_url,
 | 
| -              std::move(dispatcher_request), std::move(temporal_self_)));
 | 
| -  wrapper_ = wrapper.get();
 | 
| -  dispatcher_->RegisterWorker(params.embedded_worker_id, std::move(wrapper));
 | 
| +
 | 
| +  wrapper_ = StartWorkerContext(
 | 
| +      params,
 | 
| +      base::MakeUnique<ServiceWorkerContextClient>(
 | 
| +          params.embedded_worker_id, params.service_worker_version_id,
 | 
| +          params.scope, params.script_url, std::move(dispatcher_request),
 | 
| +          std::move(instance_host), std::move(temporal_self_)));
 | 
|  }
 | 
|  
 | 
| -void EmbeddedWorkerInstanceClientImpl::StopWorker(
 | 
| -    const StopWorkerCallback& callback) {
 | 
| +void EmbeddedWorkerInstanceClientImpl::StopWorker() {
 | 
|    // StopWorker must be called after StartWorker is called.
 | 
|    DCHECK(ChildThreadImpl::current());
 | 
|    DCHECK(wrapper_);
 | 
| -  DCHECK(embedded_worker_id_);
 | 
| -  DCHECK(!stop_callback_);
 | 
| +  DCHECK(!stop_worker_time_.has_value());
 | 
|  
 | 
|    TRACE_EVENT0("ServiceWorker", "EmbeddedWorkerInstanceClientImpl::StopWorker");
 | 
| -  stop_callback_ = callback;
 | 
| -  dispatcher_->RecordStopWorkerTimer(embedded_worker_id_.value());
 | 
| +  stop_worker_time_ = base::TimeTicks::Now();
 | 
|    wrapper_->worker()->TerminateWorkerContext();
 | 
|  }
 | 
|  
 | 
| @@ -95,12 +95,8 @@ void EmbeddedWorkerInstanceClientImpl::AddMessageToConsole(
 | 
|  }
 | 
|  
 | 
|  EmbeddedWorkerInstanceClientImpl::EmbeddedWorkerInstanceClientImpl(
 | 
| -    EmbeddedWorkerDispatcher* dispatcher,
 | 
|      mojo::InterfaceRequest<mojom::EmbeddedWorkerInstanceClient> request)
 | 
| -    : dispatcher_(dispatcher),
 | 
| -      binding_(this, std::move(request)),
 | 
| -      temporal_self_(std::unique_ptr<EmbeddedWorkerInstanceClientImpl>(this)),
 | 
| -      wrapper_(nullptr) {
 | 
| +    : binding_(this, std::move(request)), temporal_self_(this) {
 | 
|    binding_.set_connection_error_handler(base::Bind(
 | 
|        &EmbeddedWorkerInstanceClientImpl::OnError, base::Unretained(this)));
 | 
|  }
 | 
| @@ -112,4 +108,32 @@ void EmbeddedWorkerInstanceClientImpl::OnError() {
 | 
|    temporal_self_.reset();
 | 
|  }
 | 
|  
 | 
| +std::unique_ptr<EmbeddedWorkerInstanceClientImpl::WorkerWrapper>
 | 
| +EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
 | 
| +    const EmbeddedWorkerStartParams& params,
 | 
| +    std::unique_ptr<ServiceWorkerContextClient> context_client) {
 | 
| +  auto wrapper = base::MakeUnique<WorkerWrapper>(
 | 
| +      blink::WebEmbeddedWorker::Create(context_client.release(), nullptr),
 | 
| +      params.worker_devtools_agent_route_id);
 | 
| +
 | 
| +  blink::WebEmbeddedWorkerStartData start_data;
 | 
| +  start_data.script_url = params.script_url;
 | 
| +  start_data.user_agent =
 | 
| +      blink::WebString::FromUTF8(GetContentClient()->GetUserAgent());
 | 
| +  start_data.wait_for_debugger_mode =
 | 
| +      params.wait_for_debugger
 | 
| +          ? blink::WebEmbeddedWorkerStartData::kWaitForDebugger
 | 
| +          : blink::WebEmbeddedWorkerStartData::kDontWaitForDebugger;
 | 
| +  start_data.v8_cache_options = static_cast<blink::WebSettings::V8CacheOptions>(
 | 
| +      params.settings.v8_cache_options);
 | 
| +  start_data.data_saver_enabled = params.settings.data_saver_enabled;
 | 
| +  start_data.pause_after_download_mode =
 | 
| +      params.pause_after_download
 | 
| +          ? blink::WebEmbeddedWorkerStartData::kPauseAfterDownload
 | 
| +          : blink::WebEmbeddedWorkerStartData::kDontPauseAfterDownload;
 | 
| +
 | 
| +  wrapper->worker()->StartWorkerContext(start_data);
 | 
| +  return wrapper;
 | 
| +}
 | 
| +
 | 
|  }  // namespace content
 | 
| 
 |