1 // Copyright 2014 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.
5 #include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "content/child/appcache/appcache_dispatcher.h"
9 #include "content/child/appcache/web_application_cache_host_impl.h"
10 #include "content/child/scoped_child_process_reference.h"
11 #include "content/child/shared_worker_devtools_agent.h"
12 #include "content/child/webmessageportchannel_impl.h"
13 #include "content/common/worker_messages.h"
14 #include "content/renderer/render_thread_impl.h"
15 #include "content/renderer/shared_worker/embedded_shared_worker_permission_client_proxy.h"
16 #include "ipc/ipc_message_macros.h"
17 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
18 #include "third_party/WebKit/public/web/WebSharedWorker.h"
19 #include "third_party/WebKit/public/web/WebSharedWorkerClient.h"
25 class SharedWorkerWebApplicationCacheHostImpl
26 : public WebApplicationCacheHostImpl
{
28 SharedWorkerWebApplicationCacheHostImpl(
29 blink::WebApplicationCacheHostClient
* client
)
30 : WebApplicationCacheHostImpl(client
,
31 RenderThreadImpl::current()
32 ->appcache_dispatcher()
35 // Main resource loading is different for workers. The main resource is
36 // loaded by the worker using WorkerScriptLoader.
37 // These overrides are stubbed out.
38 virtual void willStartMainResourceRequest(
39 blink::WebURLRequest
&,
40 const blink::WebApplicationCacheHost
*) {}
41 virtual void didReceiveResponseForMainResource(const blink::WebURLResponse
&) {
43 virtual void didReceiveDataForMainResource(const char* data
, int len
) {}
44 virtual void didFinishLoadingMainResource(bool success
) {}
46 // Cache selection is also different for workers. We know at construction
47 // time what cache to select and do so then.
48 // These overrides are stubbed out.
49 virtual void selectCacheWithoutManifest() {}
50 virtual bool selectCacheWithManifest(const blink::WebURL
& manifestURL
) {
56 EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
58 const base::string16
& name
,
59 const base::string16
& content_security_policy
,
60 blink::WebContentSecurityPolicyType security_policy_type
,
63 : route_id_(route_id
), name_(name
), runing_(false), url_(url
) {
64 RenderThreadImpl::current()->AddEmbeddedWorkerRoute(route_id_
, this);
65 impl_
= blink::WebSharedWorker::create(this);
67 // Pause worker context when it starts and wait until either DevTools client
68 // is attached or explicit resume notification is received.
69 impl_
->pauseWorkerContextOnStart();
71 worker_devtools_agent_
.reset(
72 new SharedWorkerDevToolsAgent(route_id
, impl_
));
73 impl_
->startWorkerContext(url
, name_
,
74 content_security_policy
, security_policy_type
);
77 EmbeddedSharedWorkerStub::~EmbeddedSharedWorkerStub() {
78 RenderThreadImpl::current()->RemoveEmbeddedWorkerRoute(route_id_
);
81 bool EmbeddedSharedWorkerStub::OnMessageReceived(
82 const IPC::Message
& message
) {
83 if (worker_devtools_agent_
->OnMessageReceived(message
))
86 IPC_BEGIN_MESSAGE_MAP(EmbeddedSharedWorkerStub
, message
)
87 IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext
,
88 OnTerminateWorkerContext
)
89 IPC_MESSAGE_HANDLER(WorkerMsg_Connect
, OnConnect
)
90 IPC_MESSAGE_UNHANDLED(handled
= false)
95 void EmbeddedSharedWorkerStub::OnChannelError() {
96 OnTerminateWorkerContext();
99 void EmbeddedSharedWorkerStub::workerReadyForInspection() {
100 Send(new WorkerHostMsg_WorkerReadyForInspection(route_id_
));
103 void EmbeddedSharedWorkerStub::workerScriptLoaded() {
104 Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_
));
106 // Process any pending connections.
107 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
108 iter
!= pending_channels_
.end();
110 ConnectToChannel(*iter
);
112 pending_channels_
.clear();
115 void EmbeddedSharedWorkerStub::workerScriptLoadFailed() {
116 Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_
));
117 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
118 iter
!= pending_channels_
.end();
120 blink::WebMessagePortChannel
* channel
= *iter
;
123 pending_channels_
.clear();
127 void EmbeddedSharedWorkerStub::workerContextClosed() {
128 Send(new WorkerHostMsg_WorkerContextClosed(route_id_
));
131 void EmbeddedSharedWorkerStub::workerContextDestroyed() {
132 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_
));
136 void EmbeddedSharedWorkerStub::selectAppCacheID(long long app_cache_id
) {
137 if (app_cache_host_
) {
138 // app_cache_host_ could become stale as it's owned by blink's
139 // DocumentLoader. This method is assumed to be called while it's valid.
140 app_cache_host_
->backend()->SelectCacheForSharedWorker(
141 app_cache_host_
->host_id(), app_cache_id
);
145 blink::WebNotificationPresenter
*
146 EmbeddedSharedWorkerStub::notificationPresenter() {
147 // TODO(horo): delete this method if we have no plan to implement this.
152 blink::WebApplicationCacheHost
*
153 EmbeddedSharedWorkerStub::createApplicationCacheHost(
154 blink::WebApplicationCacheHostClient
* client
) {
155 app_cache_host_
= new SharedWorkerWebApplicationCacheHostImpl(client
);
156 return app_cache_host_
;
159 blink::WebWorkerPermissionClientProxy
*
160 EmbeddedSharedWorkerStub::createWorkerPermissionClientProxy(
161 const blink::WebSecurityOrigin
& origin
) {
162 return new EmbeddedSharedWorkerPermissionClientProxy(
163 GURL(origin
.toString()),
166 ChildThread::current()->thread_safe_sender());
169 void EmbeddedSharedWorkerStub::dispatchDevToolsMessage(
170 const blink::WebString
& message
) {
171 worker_devtools_agent_
->SendDevToolsMessage(message
);
174 void EmbeddedSharedWorkerStub::saveDevToolsAgentState(
175 const blink::WebString
& state
) {
176 worker_devtools_agent_
->SaveDevToolsAgentState(state
);
179 void EmbeddedSharedWorkerStub::Shutdown() {
183 bool EmbeddedSharedWorkerStub::Send(IPC::Message
* message
) {
184 return RenderThreadImpl::current()->Send(message
);
187 void EmbeddedSharedWorkerStub::ConnectToChannel(
188 WebMessagePortChannelImpl
* channel
) {
189 impl_
->connect(channel
);
191 new WorkerHostMsg_WorkerConnected(channel
->message_port_id(), route_id_
));
194 void EmbeddedSharedWorkerStub::OnConnect(int sent_message_port_id
,
196 WebMessagePortChannelImpl
* channel
=
197 new WebMessagePortChannelImpl(routing_id
,
198 sent_message_port_id
,
199 base::MessageLoopProxy::current().get());
201 ConnectToChannel(channel
);
203 // If two documents try to load a SharedWorker at the same time, the
204 // WorkerMsg_Connect for one of the documents can come in before the
205 // worker is started. Just queue up the connect and deliver it once the
207 pending_channels_
.push_back(channel
);
211 void EmbeddedSharedWorkerStub::OnTerminateWorkerContext() {
213 impl_
->terminateWorkerContext();
216 } // namespace content