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
, unsigned 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
) {
57 EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
59 const base::string16
& name
,
60 const base::string16
& content_security_policy
,
61 blink::WebContentSecurityPolicyType security_policy_type
,
64 : route_id_(route_id
),
68 app_cache_host_(nullptr) {
69 RenderThreadImpl::current()->AddEmbeddedWorkerRoute(route_id_
, this);
70 impl_
= blink::WebSharedWorker::create(this);
72 // Pause worker context when it starts and wait until either DevTools client
73 // is attached or explicit resume notification is received.
74 impl_
->pauseWorkerContextOnStart();
76 worker_devtools_agent_
.reset(
77 new SharedWorkerDevToolsAgent(route_id
, impl_
));
78 impl_
->startWorkerContext(url
, name_
,
79 content_security_policy
, security_policy_type
);
82 EmbeddedSharedWorkerStub::~EmbeddedSharedWorkerStub() {
83 RenderThreadImpl::current()->RemoveEmbeddedWorkerRoute(route_id_
);
86 bool EmbeddedSharedWorkerStub::OnMessageReceived(
87 const IPC::Message
& message
) {
88 if (worker_devtools_agent_
->OnMessageReceived(message
))
91 IPC_BEGIN_MESSAGE_MAP(EmbeddedSharedWorkerStub
, message
)
92 IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext
,
93 OnTerminateWorkerContext
)
94 IPC_MESSAGE_HANDLER(WorkerMsg_Connect
, OnConnect
)
95 IPC_MESSAGE_UNHANDLED(handled
= false)
100 void EmbeddedSharedWorkerStub::OnChannelError() {
101 OnTerminateWorkerContext();
104 void EmbeddedSharedWorkerStub::workerReadyForInspection() {
105 Send(new WorkerHostMsg_WorkerReadyForInspection(route_id_
));
108 void EmbeddedSharedWorkerStub::workerScriptLoaded() {
109 Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_
));
111 // Process any pending connections.
112 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
113 iter
!= pending_channels_
.end();
115 ConnectToChannel(*iter
);
117 pending_channels_
.clear();
120 void EmbeddedSharedWorkerStub::workerScriptLoadFailed() {
121 Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_
));
122 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
123 iter
!= pending_channels_
.end();
125 blink::WebMessagePortChannel
* channel
= *iter
;
128 pending_channels_
.clear();
132 void EmbeddedSharedWorkerStub::workerContextClosed() {
133 Send(new WorkerHostMsg_WorkerContextClosed(route_id_
));
136 void EmbeddedSharedWorkerStub::workerContextDestroyed() {
137 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_
));
141 void EmbeddedSharedWorkerStub::selectAppCacheID(long long app_cache_id
) {
142 if (app_cache_host_
) {
143 // app_cache_host_ could become stale as it's owned by blink's
144 // DocumentLoader. This method is assumed to be called while it's valid.
145 app_cache_host_
->backend()->SelectCacheForSharedWorker(
146 app_cache_host_
->host_id(), app_cache_id
);
150 blink::WebNotificationPresenter
*
151 EmbeddedSharedWorkerStub::notificationPresenter() {
152 // TODO(horo): delete this method if we have no plan to implement this.
157 blink::WebApplicationCacheHost
*
158 EmbeddedSharedWorkerStub::createApplicationCacheHost(
159 blink::WebApplicationCacheHostClient
* client
) {
160 app_cache_host_
= new SharedWorkerWebApplicationCacheHostImpl(client
);
161 return app_cache_host_
;
164 blink::WebWorkerPermissionClientProxy
*
165 EmbeddedSharedWorkerStub::createWorkerPermissionClientProxy(
166 const blink::WebSecurityOrigin
& origin
) {
167 return new EmbeddedSharedWorkerPermissionClientProxy(
168 GURL(origin
.toString()),
171 ChildThreadImpl::current()->thread_safe_sender());
174 void EmbeddedSharedWorkerStub::sendDevToolsMessage(
176 const blink::WebString
& message
,
177 const blink::WebString
& state
) {
178 worker_devtools_agent_
->SendDevToolsMessage(call_id
, message
, state
);
181 void EmbeddedSharedWorkerStub::Shutdown() {
185 bool EmbeddedSharedWorkerStub::Send(IPC::Message
* message
) {
186 return RenderThreadImpl::current()->Send(message
);
189 void EmbeddedSharedWorkerStub::ConnectToChannel(
190 WebMessagePortChannelImpl
* channel
) {
191 impl_
->connect(channel
);
193 new WorkerHostMsg_WorkerConnected(channel
->message_port_id(), route_id_
));
196 void EmbeddedSharedWorkerStub::OnConnect(int sent_message_port_id
,
198 WebMessagePortChannelImpl
* channel
=
199 new WebMessagePortChannelImpl(routing_id
,
200 sent_message_port_id
,
201 base::MessageLoopProxy::current().get());
203 ConnectToChannel(channel
);
205 // If two documents try to load a SharedWorker at the same time, the
206 // WorkerMsg_Connect for one of the documents can come in before the
207 // worker is started. Just queue up the connect and deliver it once the
209 pending_channels_
.push_back(channel
);
213 void EmbeddedSharedWorkerStub::OnTerminateWorkerContext() {
215 impl_
->terminateWorkerContext();
218 } // namespace content