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/webmessageportchannel_impl.h" 11 #include "content/common/worker_messages.h" 12 #include "content/public/common/content_switches.h" 13 #include "content/worker/shared_worker_devtools_agent.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 } 47 48 WebSharedWorkerClientProxy::~WebSharedWorkerClientProxy() { 49 } 50 51 void WebSharedWorkerClientProxy::workerContextClosed() { 52 Send(new WorkerHostMsg_WorkerContextClosed(route_id_)); 53 } 54 55 void WebSharedWorkerClientProxy::workerContextDestroyed() { 56 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_)); 57 // Tell the stub that the worker has shutdown - frees this object. 58 if (stub_) 59 stub_->Shutdown(); 60 } 61 62 blink::WebNotificationPresenter* 63 WebSharedWorkerClientProxy::notificationPresenter() { 64 // TODO(johnnyg): Notifications are not yet hooked up to workers. 65 // Coming soon. 66 NOTREACHED(); 67 return NULL; 68 } 69 70 WebApplicationCacheHost* WebSharedWorkerClientProxy::createApplicationCacheHost( 71 blink::WebApplicationCacheHostClient* client) { 72 WorkerWebApplicationCacheHostImpl* host = 73 new WorkerWebApplicationCacheHostImpl(stub_->appcache_init_info(), 74 client); 75 // Remember the id of the instance we create so we have access to that 76 // value when creating nested dedicated workers in createWorker. 77 appcache_host_id_ = host->host_id(); 78 return host; 79 } 80 81 blink::WebWorkerPermissionClientProxy* 82 WebSharedWorkerClientProxy::createWorkerPermissionClientProxy( 83 const blink::WebSecurityOrigin& origin) { 84 return new SharedWorkerPermissionClientProxy( 85 GURL(origin.toString()), origin.isUnique(), route_id_, 86 ChildThread::current()->thread_safe_sender()); 87 } 88 89 // TODO(kinuko): Deprecate these methods. 90 bool WebSharedWorkerClientProxy::allowDatabase(WebFrame* frame, 91 const WebString& name, 92 const WebString& display_name, 93 unsigned long estimated_size) { 94 return false; 95 } 96 97 bool WebSharedWorkerClientProxy::allowFileSystem() { 98 return false; 99 } 100 101 bool WebSharedWorkerClientProxy::allowIndexedDB(const blink::WebString& name) { 102 return false; 103 } 104 105 void WebSharedWorkerClientProxy::dispatchDevToolsMessage( 106 const WebString& message) { 107 if (devtools_agent_) 108 devtools_agent_->SendDevToolsMessage(message); 109 } 110 111 void WebSharedWorkerClientProxy::saveDevToolsAgentState( 112 const blink::WebString& state) { 113 if (devtools_agent_) 114 devtools_agent_->SaveDevToolsAgentState(state); 115 } 116 117 bool WebSharedWorkerClientProxy::Send(IPC::Message* message) { 118 return WorkerThread::current()->Send(message); 119 } 120 121 void WebSharedWorkerClientProxy::EnsureWorkerContextTerminates() { 122 // This shuts down the process cleanly from the perspective of the browser 123 // process, and avoids the crashed worker infobar from appearing to the new 124 // page. It's ok to post several of theese, because the first executed task 125 // will exit the message loop and subsequent ones won't be executed. 126 base::MessageLoop::current()->PostDelayedTask( 127 FROM_HERE, 128 base::Bind(&WebSharedWorkerClientProxy::workerContextDestroyed, 129 weak_factory_.GetWeakPtr()), 130 base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds)); 131 } 132 133 } // namespace content 134