Home | History | Annotate | Download | only in service_worker
      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
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/service_worker/embedded_worker_dispatcher.h"
      6 
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/strings/string16.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "content/child/child_process.h"
     11 #include "content/child/scoped_child_process_reference.h"
     12 #include "content/child/thread_safe_sender.h"
     13 #include "content/child/worker_task_runner.h"
     14 #include "content/common/devtools_messages.h"
     15 #include "content/common/service_worker/embedded_worker_messages.h"
     16 #include "content/public/common/content_client.h"
     17 #include "content/renderer/render_thread_impl.h"
     18 #include "content/renderer/service_worker/embedded_worker_context_client.h"
     19 #include "content/renderer/service_worker/embedded_worker_devtools_agent.h"
     20 #include "third_party/WebKit/public/platform/WebString.h"
     21 #include "third_party/WebKit/public/platform/WebURL.h"
     22 #include "third_party/WebKit/public/web/WebEmbeddedWorker.h"
     23 #include "third_party/WebKit/public/web/WebEmbeddedWorkerStartData.h"
     24 
     25 namespace content {
     26 
     27 // A thin wrapper of WebEmbeddedWorker which also adds and releases process
     28 // references automatically.
     29 class EmbeddedWorkerDispatcher::WorkerWrapper {
     30  public:
     31   WorkerWrapper(blink::WebEmbeddedWorker* worker, int devtools_agent_route_id)
     32       : worker_(worker),
     33         dev_tools_agent_(
     34             new EmbeddedWorkerDevToolsAgent(worker, devtools_agent_route_id)) {}
     35   ~WorkerWrapper() {}
     36 
     37   blink::WebEmbeddedWorker* worker() { return worker_.get(); }
     38 
     39  private:
     40   ScopedChildProcessReference process_ref_;
     41   scoped_ptr<blink::WebEmbeddedWorker> worker_;
     42   scoped_ptr<EmbeddedWorkerDevToolsAgent> dev_tools_agent_;
     43 };
     44 
     45 EmbeddedWorkerDispatcher::EmbeddedWorkerDispatcher() : weak_factory_(this) {}
     46 
     47 EmbeddedWorkerDispatcher::~EmbeddedWorkerDispatcher() {}
     48 
     49 bool EmbeddedWorkerDispatcher::OnMessageReceived(
     50     const IPC::Message& message) {
     51   bool handled = true;
     52   IPC_BEGIN_MESSAGE_MAP(EmbeddedWorkerDispatcher, message)
     53     IPC_MESSAGE_HANDLER(EmbeddedWorkerMsg_StartWorker, OnStartWorker)
     54     IPC_MESSAGE_HANDLER(EmbeddedWorkerMsg_StopWorker, OnStopWorker)
     55     IPC_MESSAGE_UNHANDLED(handled = false)
     56   IPC_END_MESSAGE_MAP()
     57   return handled;
     58 }
     59 
     60 void EmbeddedWorkerDispatcher::WorkerContextDestroyed(
     61     int embedded_worker_id) {
     62   RenderThreadImpl::current()->thread_safe_sender()->Send(
     63       new EmbeddedWorkerHostMsg_WorkerStopped(embedded_worker_id));
     64   workers_.Remove(embedded_worker_id);
     65 }
     66 
     67 void EmbeddedWorkerDispatcher::OnStartWorker(
     68     const EmbeddedWorkerMsg_StartWorker_Params& params) {
     69   DCHECK(!workers_.Lookup(params.embedded_worker_id));
     70   RenderThread::Get()->EnsureWebKitInitialized();
     71   scoped_ptr<WorkerWrapper> wrapper(
     72       new WorkerWrapper(blink::WebEmbeddedWorker::create(
     73                             new EmbeddedWorkerContextClient(
     74                                 params.embedded_worker_id,
     75                                 params.service_worker_version_id,
     76                                 params.scope,
     77                                 params.script_url,
     78                                 params.worker_devtools_agent_route_id),
     79                             NULL),
     80                         params.worker_devtools_agent_route_id));
     81 
     82   blink::WebEmbeddedWorkerStartData start_data;
     83   start_data.scriptURL = params.script_url;
     84   start_data.userAgent = base::UTF8ToUTF16(GetContentClient()->GetUserAgent());
     85   start_data.startMode =
     86       params.pause_on_start ? blink::WebEmbeddedWorkerStartModePauseOnStart
     87                             : blink::WebEmbeddedWorkerStartModeDontPauseOnStart;
     88 
     89   wrapper->worker()->startWorkerContext(start_data);
     90   workers_.AddWithID(wrapper.release(), params.embedded_worker_id);
     91 }
     92 
     93 void EmbeddedWorkerDispatcher::OnStopWorker(int embedded_worker_id) {
     94   WorkerWrapper* wrapper = workers_.Lookup(embedded_worker_id);
     95   if (!wrapper) {
     96     LOG(WARNING) << "Got OnStopWorker for nonexistent worker";
     97     return;
     98   }
     99 
    100   // This should eventually call WorkerContextDestroyed. (We may need to post
    101   // a delayed task to forcibly abort the worker context if we find it
    102   // necessary)
    103   wrapper->worker()->terminateWorkerContext();
    104 }
    105 
    106 }  // namespace content
    107