Home | History | Annotate | Download | only in worker
      1 // Copyright (c) 2012 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/worker/websharedworkerclient_proxy.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/command_line.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "content/child/shared_worker_devtools_agent.h"
     11 #include "content/child/webmessageportchannel_impl.h"
     12 #include "content/common/worker_messages.h"
     13 #include "content/public/common/content_switches.h"
     14 #include "content/worker/shared_worker_permission_client_proxy.h"
     15 #include "content/worker/websharedworker_stub.h"
     16 #include "content/worker/worker_thread.h"
     17 #include "content/worker/worker_webapplicationcachehost_impl.h"
     18 #include "ipc/ipc_logging.h"
     19 #include "third_party/WebKit/public/platform/WebString.h"
     20 #include "third_party/WebKit/public/platform/WebURL.h"
     21 #include "third_party/WebKit/public/web/WebDocument.h"
     22 #include "third_party/WebKit/public/web/WebFrame.h"
     23 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
     24 
     25 using blink::WebApplicationCacheHost;
     26 using blink::WebFrame;
     27 using blink::WebMessagePortChannel;
     28 using blink::WebMessagePortChannelArray;
     29 using blink::WebSecurityOrigin;
     30 using blink::WebString;
     31 using blink::WebWorker;
     32 using blink::WebSharedWorkerClient;
     33 
     34 namespace content {
     35 
     36 // How long to wait for worker to finish after it's been told to terminate.
     37 #define kMaxTimeForRunawayWorkerSeconds 3
     38 
     39 WebSharedWorkerClientProxy::WebSharedWorkerClientProxy(
     40     int route_id, WebSharedWorkerStub* stub)
     41     : route_id_(route_id),
     42       appcache_host_id_(0),
     43       stub_(stub),
     44       weak_factory_(this),
     45       devtools_agent_(NULL),
     46       app_cache_host_(NULL) {
     47 }
     48 
     49 WebSharedWorkerClientProxy::~WebSharedWorkerClientProxy() {
     50 }
     51 
     52 void WebSharedWorkerClientProxy::workerContextClosed() {
     53   Send(new WorkerHostMsg_WorkerContextClosed(route_id_));
     54 }
     55 
     56 void WebSharedWorkerClientProxy::workerContextDestroyed() {
     57   Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_));
     58   // Tell the stub that the worker has shutdown - frees this object.
     59   if (stub_)
     60     stub_->Shutdown();
     61 }
     62 
     63 void WebSharedWorkerClientProxy::workerScriptLoaded() {
     64   Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_));
     65   if (stub_)
     66     stub_->WorkerScriptLoaded();
     67 }
     68 
     69 void WebSharedWorkerClientProxy::workerScriptLoadFailed() {
     70   Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_));
     71   if (stub_)
     72     stub_->WorkerScriptLoadFailed();
     73 }
     74 
     75 void WebSharedWorkerClientProxy::selectAppCacheID(long long app_cache_id) {
     76   if (app_cache_host_) {
     77     // app_cache_host_ could become stale as it's owned by blink's
     78     // DocumentLoader. This method is assumed to be called while it's valid.
     79     app_cache_host_->backend()->SelectCacheForSharedWorker(
     80         app_cache_host_->host_id(),
     81         app_cache_id);
     82   }
     83 }
     84 
     85 blink::WebNotificationPresenter*
     86 WebSharedWorkerClientProxy::notificationPresenter() {
     87   // TODO(johnnyg): Notifications are not yet hooked up to workers.
     88   // Coming soon.
     89   NOTREACHED();
     90   return NULL;
     91 }
     92 
     93 WebApplicationCacheHost* WebSharedWorkerClientProxy::createApplicationCacheHost(
     94     blink::WebApplicationCacheHostClient* client) {
     95   DCHECK(!app_cache_host_);
     96   app_cache_host_ = new WorkerWebApplicationCacheHostImpl(client);
     97   // Remember the id of the instance we create so we have access to that
     98   // value when creating nested dedicated workers in createWorker.
     99   appcache_host_id_ = app_cache_host_->host_id();
    100   return app_cache_host_;
    101 }
    102 
    103 blink::WebWorkerPermissionClientProxy*
    104 WebSharedWorkerClientProxy::createWorkerPermissionClientProxy(
    105     const blink::WebSecurityOrigin& origin) {
    106   return new SharedWorkerPermissionClientProxy(
    107       GURL(origin.toString()), origin.isUnique(), route_id_,
    108       ChildThread::current()->thread_safe_sender());
    109 }
    110 
    111 void WebSharedWorkerClientProxy::dispatchDevToolsMessage(
    112     const WebString& message) {
    113   if (devtools_agent_)
    114     devtools_agent_->SendDevToolsMessage(message);
    115 }
    116 
    117 void WebSharedWorkerClientProxy::saveDevToolsAgentState(
    118     const blink::WebString& state) {
    119   if (devtools_agent_)
    120     devtools_agent_->SaveDevToolsAgentState(state);
    121 }
    122 
    123 bool WebSharedWorkerClientProxy::Send(IPC::Message* message) {
    124   return WorkerThread::current()->Send(message);
    125 }
    126 
    127 void WebSharedWorkerClientProxy::EnsureWorkerContextTerminates() {
    128   // This shuts down the process cleanly from the perspective of the browser
    129   // process, and avoids the crashed worker infobar from appearing to the new
    130   // page. It's ok to post several of theese, because the first executed task
    131   // will exit the message loop and subsequent ones won't be executed.
    132   base::MessageLoop::current()->PostDelayedTask(
    133       FROM_HERE,
    134       base::Bind(&WebSharedWorkerClientProxy::workerContextDestroyed,
    135                  weak_factory_.GetWeakPtr()),
    136       base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds));
    137 }
    138 
    139 }  // namespace content
    140