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 "ipc/ipc_message_macros.h"
16 #include "third_party/WebKit/public/web/WebSharedWorker.h"
17 #include "third_party/WebKit/public/web/WebSharedWorkerClient.h"
23 class SharedWorkerWebApplicationCacheHostImpl
24 : public WebApplicationCacheHostImpl
{
26 SharedWorkerWebApplicationCacheHostImpl(
27 blink::WebApplicationCacheHostClient
* client
)
28 : WebApplicationCacheHostImpl(client
,
29 RenderThreadImpl::current()
30 ->appcache_dispatcher()
33 // Main resource loading is different for workers. The main resource is
34 // loaded by the worker using WorkerScriptLoader.
35 // These overrides are stubbed out.
36 virtual void willStartMainResourceRequest(
37 blink::WebURLRequest
&,
38 const blink::WebApplicationCacheHost
*) {}
39 virtual void didReceiveResponseForMainResource(const blink::WebURLResponse
&) {
41 virtual void didReceiveDataForMainResource(const char* data
, int len
) {}
42 virtual void didFinishLoadingMainResource(bool success
) {}
44 // Cache selection is also different for workers. We know at construction
45 // time what cache to select and do so then.
46 // These overrides are stubbed out.
47 virtual void selectCacheWithoutManifest() {}
48 virtual bool selectCacheWithManifest(const blink::WebURL
& manifestURL
) {
54 EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
56 const base::string16
& name
,
57 const base::string16
& content_security_policy
,
58 blink::WebContentSecurityPolicyType security_policy_type
,
61 : route_id_(route_id
), name_(name
), runing_(false), url_(url
) {
62 RenderThreadImpl::current()->AddEmbeddedWorkerRoute(route_id_
, this);
63 impl_
= blink::WebSharedWorker::create(this);
65 // Pause worker context when it starts and wait until either DevTools client
66 // is attached or explicit resume notification is received.
67 impl_
->pauseWorkerContextOnStart();
69 worker_devtools_agent_
.reset(
70 new SharedWorkerDevToolsAgent(route_id
, impl_
));
71 impl_
->startWorkerContext(url
, name_
,
72 content_security_policy
, security_policy_type
);
75 EmbeddedSharedWorkerStub::~EmbeddedSharedWorkerStub() {
76 RenderThreadImpl::current()->RemoveEmbeddedWorkerRoute(route_id_
);
79 bool EmbeddedSharedWorkerStub::OnMessageReceived(
80 const IPC::Message
& message
) {
81 if (worker_devtools_agent_
->OnMessageReceived(message
))
84 IPC_BEGIN_MESSAGE_MAP(EmbeddedSharedWorkerStub
, message
)
85 IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext
,
86 OnTerminateWorkerContext
)
87 IPC_MESSAGE_HANDLER(WorkerMsg_Connect
, OnConnect
)
88 IPC_MESSAGE_UNHANDLED(handled
= false)
93 void EmbeddedSharedWorkerStub::OnChannelError() {
94 OnTerminateWorkerContext();
97 void EmbeddedSharedWorkerStub::workerScriptLoaded() {
98 Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_
));
100 // Process any pending connections.
101 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
102 iter
!= pending_channels_
.end();
104 ConnectToChannel(*iter
);
106 pending_channels_
.clear();
109 void EmbeddedSharedWorkerStub::workerScriptLoadFailed() {
110 Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_
));
111 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
112 iter
!= pending_channels_
.end();
114 blink::WebMessagePortChannel
* channel
= *iter
;
117 pending_channels_
.clear();
121 void EmbeddedSharedWorkerStub::workerContextClosed() {
122 Send(new WorkerHostMsg_WorkerContextClosed(route_id_
));
125 void EmbeddedSharedWorkerStub::workerContextDestroyed() {
126 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_
));
130 void EmbeddedSharedWorkerStub::selectAppCacheID(long long app_cache_id
) {
131 if (app_cache_host_
) {
132 // app_cache_host_ could become stale as it's owned by blink's
133 // DocumentLoader. This method is assumed to be called while it's valid.
134 app_cache_host_
->backend()->SelectCacheForSharedWorker(
135 app_cache_host_
->host_id(), app_cache_id
);
139 blink::WebNotificationPresenter
*
140 EmbeddedSharedWorkerStub::notificationPresenter() {
141 // TODO(horo): delete this method if we have no plan to implement this.
146 blink::WebApplicationCacheHost
*
147 EmbeddedSharedWorkerStub::createApplicationCacheHost(
148 blink::WebApplicationCacheHostClient
* client
) {
149 app_cache_host_
= new SharedWorkerWebApplicationCacheHostImpl(client
);
150 return app_cache_host_
;
153 blink::WebWorkerPermissionClientProxy
*
154 EmbeddedSharedWorkerStub::createWorkerPermissionClientProxy(
155 const blink::WebSecurityOrigin
& origin
) {
156 // TODO(horo): implement this.
160 void EmbeddedSharedWorkerStub::dispatchDevToolsMessage(
161 const blink::WebString
& message
) {
162 worker_devtools_agent_
->SendDevToolsMessage(message
);
165 void EmbeddedSharedWorkerStub::saveDevToolsAgentState(
166 const blink::WebString
& state
) {
167 worker_devtools_agent_
->SaveDevToolsAgentState(state
);
170 void EmbeddedSharedWorkerStub::Shutdown() {
174 bool EmbeddedSharedWorkerStub::Send(IPC::Message
* message
) {
175 return RenderThreadImpl::current()->Send(message
);
178 void EmbeddedSharedWorkerStub::ConnectToChannel(
179 WebMessagePortChannelImpl
* channel
) {
180 impl_
->connect(channel
);
182 new WorkerHostMsg_WorkerConnected(channel
->message_port_id(), route_id_
));
185 void EmbeddedSharedWorkerStub::OnConnect(int sent_message_port_id
,
187 WebMessagePortChannelImpl
* channel
=
188 new WebMessagePortChannelImpl(routing_id
,
189 sent_message_port_id
,
190 base::MessageLoopProxy::current().get());
192 ConnectToChannel(channel
);
194 // If two documents try to load a SharedWorker at the same time, the
195 // WorkerMsg_Connect for one of the documents can come in before the
196 // worker is started. Just queue up the connect and deliver it once the
198 pending_channels_
.push_back(channel
);
202 void EmbeddedSharedWorkerStub::OnTerminateWorkerContext() {
204 impl_
->terminateWorkerContext();
207 } // namespace content