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.
5 #include "content/worker/websharedworker_stub.h"
7 #include "base/command_line.h"
8 #include "base/compiler_specific.h"
9 #include "content/child/child_process.h"
10 #include "content/child/child_thread.h"
11 #include "content/child/fileapi/file_system_dispatcher.h"
12 #include "content/child/shared_worker_devtools_agent.h"
13 #include "content/child/webmessageportchannel_impl.h"
14 #include "content/common/worker_messages.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/worker/worker_thread.h"
17 #include "third_party/WebKit/public/platform/WebString.h"
18 #include "third_party/WebKit/public/platform/WebURL.h"
19 #include "third_party/WebKit/public/web/WebSharedWorker.h"
23 WebSharedWorkerStub::WebSharedWorkerStub(
25 const base::string16
& name
,
26 const base::string16
& content_security_policy
,
27 blink::WebContentSecurityPolicyType security_policy_type
,
30 : route_id_(route_id
),
31 client_(route_id
, this),
35 WorkerThread
* worker_thread
= WorkerThread::current();
36 DCHECK(worker_thread
);
37 worker_thread
->AddWorkerStub(this);
38 // Start processing incoming IPCs for this worker.
39 worker_thread
->GetRouter()->AddRoute(route_id_
, this);
41 // TODO(atwilson): Add support for NaCl when they support MessagePorts.
42 impl_
= blink::WebSharedWorker::create(client());
44 // Pause worker context when it starts and wait until either DevTools client
45 // is attached or explicit resume notification is received.
46 impl_
->pauseWorkerContextOnStart();
49 worker_devtools_agent_
.reset(new SharedWorkerDevToolsAgent(route_id
, impl_
));
50 client()->set_devtools_agent(worker_devtools_agent_
.get());
51 impl_
->startWorkerContext(url_
, name
,
52 content_security_policy
, security_policy_type
);
55 WebSharedWorkerStub::~WebSharedWorkerStub() {
56 impl_
->clientDestroyed();
57 WorkerThread
* worker_thread
= WorkerThread::current();
58 DCHECK(worker_thread
);
59 worker_thread
->RemoveWorkerStub(this);
60 worker_thread
->GetRouter()->RemoveRoute(route_id_
);
63 void WebSharedWorkerStub::Shutdown() {
64 // The worker has exited - free ourselves and the client.
68 void WebSharedWorkerStub::EnsureWorkerContextTerminates() {
69 client_
.EnsureWorkerContextTerminates();
72 bool WebSharedWorkerStub::OnMessageReceived(const IPC::Message
& message
) {
73 if (worker_devtools_agent_
->OnMessageReceived(message
))
77 IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerStub
, message
)
78 IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext
,
79 OnTerminateWorkerContext
)
80 IPC_MESSAGE_HANDLER(WorkerMsg_Connect
, OnConnect
)
81 IPC_MESSAGE_UNHANDLED(handled
= false)
86 void WebSharedWorkerStub::OnChannelError() {
87 OnTerminateWorkerContext();
90 const GURL
& WebSharedWorkerStub::url() {
94 void WebSharedWorkerStub::OnConnect(int sent_message_port_id
, int routing_id
) {
95 WebMessagePortChannelImpl
* channel
=
96 new WebMessagePortChannelImpl(routing_id
,
98 base::MessageLoopProxy::current().get());
100 impl_
->connect(channel
);
101 WorkerThread::current()->Send(
102 new WorkerHostMsg_WorkerConnected(channel
->message_port_id(),
105 // If two documents try to load a SharedWorker at the same time, the
106 // WorkerMsg_Connect for one of the documents can come in before the
107 // worker is started. Just queue up the connect and deliver it once the
109 pending_channels_
.push_back(channel
);
113 void WebSharedWorkerStub::OnTerminateWorkerContext() {
115 // Call the client to make sure context exits.
116 EnsureWorkerContextTerminates();
117 // This may call "delete this" via WorkerScriptLoadFailed and Shutdown.
118 impl_
->terminateWorkerContext();
121 void WebSharedWorkerStub::WorkerScriptLoaded() {
123 // Process any pending connections.
124 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
125 iter
!= pending_channels_
.end();
127 impl_
->connect(*iter
);
128 WorkerThread::current()->Send(
129 new WorkerHostMsg_WorkerConnected((*iter
)->message_port_id(),
132 pending_channels_
.clear();
135 void WebSharedWorkerStub::WorkerScriptLoadFailed() {
136 for (PendingChannelList::const_iterator iter
= pending_channels_
.begin();
137 iter
!= pending_channels_
.end();
139 blink::WebMessagePortChannel
* channel
= *iter
;
142 pending_channels_
.clear();
146 } // namespace content