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 "content/common/child_process.h"
8 #include "content/common/child_thread.h"
9 #include "content/common/fileapi/file_system_dispatcher.h"
10 #include "content/common/webmessageportchannel_impl.h"
11 #include "content/common/worker_messages.h"
12 #include "base/compiler_specific.h"
13 #include "content/worker/worker_thread.h"
14 #include "content/worker/shared_worker_devtools_agent.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSharedWorker.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
21 WebSharedWorkerStub::WebSharedWorkerStub(
22 const string16
& name
, int route_id
,
23 const WorkerAppCacheInitInfo
& appcache_init_info
)
24 : route_id_(route_id
),
25 appcache_init_info_(appcache_init_info
),
26 ALLOW_THIS_IN_INITIALIZER_LIST(client_(route_id
, this)),
29 worker_devtools_agent_(NULL
) {
31 WorkerThread
* worker_thread
= WorkerThread::current();
32 DCHECK(worker_thread
);
33 worker_thread
->AddWorkerStub(this);
34 // Start processing incoming IPCs for this worker.
35 worker_thread
->AddRoute(route_id_
, this);
36 ChildProcess::current()->AddRefProcess();
38 // TODO(atwilson): Add support for NaCl when they support MessagePorts.
39 impl_
= WebKit::WebSharedWorker::create(client());
40 worker_devtools_agent_
.reset(new SharedWorkerDevToolsAgent(route_id
, impl_
));
41 client()->set_devtools_agent(worker_devtools_agent_
.get());
44 WebSharedWorkerStub::~WebSharedWorkerStub() {
45 impl_
->clientDestroyed();
46 WorkerThread
* worker_thread
= WorkerThread::current();
47 DCHECK(worker_thread
);
48 worker_thread
->RemoveWorkerStub(this);
49 worker_thread
->RemoveRoute(route_id_
);
50 ChildProcess::current()->ReleaseProcess();
53 void WebSharedWorkerStub::Shutdown() {
54 // The worker has exited - free ourselves and the client.
58 void WebSharedWorkerStub::EnsureWorkerContextTerminates() {
59 client_
.EnsureWorkerContextTerminates();
62 bool WebSharedWorkerStub::OnMessageReceived(const IPC::Message
& message
) {
63 if (worker_devtools_agent_
->OnMessageReceived(message
))
67 IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerStub
, message
)
68 IPC_MESSAGE_HANDLER(WorkerMsg_StartWorkerContext
, OnStartWorkerContext
)
69 IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext
,
70 OnTerminateWorkerContext
)
71 IPC_MESSAGE_HANDLER(WorkerMsg_Connect
, OnConnect
)
72 IPC_MESSAGE_UNHANDLED(handled
= false)
77 void WebSharedWorkerStub::OnChannelError() {
78 OnTerminateWorkerContext();
81 const GURL
& WebSharedWorkerStub::url() {
85 void WebSharedWorkerStub::OnStartWorkerContext(
86 const GURL
& url
, const string16
& user_agent
, const string16
& source_code
,
87 const string16
& content_security_policy
,
88 WebKit::WebContentSecurityPolicyType policy_type
) {
89 // Ignore multiple attempts to start this worker (can happen if two pages
90 // try to start it simultaneously).
94 impl_
->startWorkerContext(url
, name_
, user_agent
, source_code
,
95 content_security_policy
, policy_type
, 0);
99 // Process any pending connections.
100 for (PendingConnectInfoList::const_iterator iter
= pending_connects_
.begin();
101 iter
!= pending_connects_
.end();
103 OnConnect(iter
->first
, iter
->second
);
105 pending_connects_
.clear();
108 void WebSharedWorkerStub::OnConnect(int sent_message_port_id
, int routing_id
) {
110 WebKit::WebMessagePortChannel
* channel
=
111 new WebMessagePortChannelImpl(routing_id
, sent_message_port_id
);
112 impl_
->connect(channel
, NULL
);
114 // If two documents try to load a SharedWorker at the same time, the
115 // WorkerMsg_Connect for one of the documents can come in before the
116 // worker is started. Just queue up the connect and deliver it once the
118 PendingConnectInfo
pending_connect(sent_message_port_id
, routing_id
);
119 pending_connects_
.push_back(pending_connect
);
123 void WebSharedWorkerStub::OnTerminateWorkerContext() {
124 impl_
->terminateWorkerContext();
126 // Call the client to make sure context exits.
127 EnsureWorkerContextTerminates();
131 } // namespace content