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/websharedworkerclient_proxy.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "content/child/webmessageportchannel_impl.h"
11 #include "content/common/worker_messages.h"
12 #include "content/public/common/content_switches.h"
13 #include "content/worker/shared_worker_devtools_agent.h"
14 #include "content/worker/websharedworker_stub.h"
15 #include "content/worker/worker_thread.h"
16 #include "content/worker/worker_webapplicationcachehost_impl.h"
17 #include "ipc/ipc_logging.h"
18 #include "third_party/WebKit/public/platform/WebString.h"
19 #include "third_party/WebKit/public/platform/WebURL.h"
20 #include "third_party/WebKit/public/web/WebDocument.h"
21 #include "third_party/WebKit/public/web/WebFrame.h"
22 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
24 using WebKit::WebApplicationCacheHost
;
25 using WebKit::WebFrame
;
26 using WebKit::WebMessagePortChannel
;
27 using WebKit::WebMessagePortChannelArray
;
28 using WebKit::WebSecurityOrigin
;
29 using WebKit::WebString
;
30 using WebKit::WebWorker
;
31 using WebKit::WebSharedWorkerClient
;
35 // How long to wait for worker to finish after it's been told to terminate.
36 #define kMaxTimeForRunawayWorkerSeconds 3
38 WebSharedWorkerClientProxy::WebSharedWorkerClientProxy(
39 int route_id
, WebSharedWorkerStub
* stub
)
40 : route_id_(route_id
),
44 devtools_agent_(NULL
) {
47 WebSharedWorkerClientProxy::~WebSharedWorkerClientProxy() {
50 void WebSharedWorkerClientProxy::postMessageToWorkerObject(
51 const WebString
& message
,
52 const WebMessagePortChannelArray
& channels
) {
53 std::vector
<int> message_port_ids(channels
.size());
54 std::vector
<int> routing_ids(channels
.size());
55 for (size_t i
= 0; i
< channels
.size(); ++i
) {
56 WebMessagePortChannelImpl
* webchannel
=
57 static_cast<WebMessagePortChannelImpl
*>(channels
[i
]);
58 message_port_ids
[i
] = webchannel
->message_port_id();
59 webchannel
->QueueMessages();
60 DCHECK(message_port_ids
[i
] != MSG_ROUTING_NONE
);
61 routing_ids
[i
] = MSG_ROUTING_NONE
;
64 Send(new WorkerMsg_PostMessage(
65 route_id_
, message
, message_port_ids
, routing_ids
));
68 void WebSharedWorkerClientProxy::postExceptionToWorkerObject(
69 const WebString
& error_message
,
71 const WebString
& source_url
) {
72 Send(new WorkerHostMsg_PostExceptionToWorkerObject(
73 route_id_
, error_message
, line_number
, source_url
));
76 void WebSharedWorkerClientProxy::postConsoleMessageToWorkerObject(
80 const WebString
& message
,
82 const WebString
& source_url
) {
83 WorkerHostMsg_PostConsoleMessageToWorkerObject_Params params
;
84 params
.source_identifier
= source
;
85 params
.message_type
= type
;
86 params
.message_level
= level
;
87 params
.message
= message
;
88 params
.line_number
= line_number
;
89 params
.source_url
= source_url
;
90 Send(new WorkerHostMsg_PostConsoleMessageToWorkerObject(route_id_
, params
));
93 void WebSharedWorkerClientProxy::confirmMessageFromWorkerObject(
94 bool has_pending_activity
) {
95 Send(new WorkerHostMsg_ConfirmMessageFromWorkerObject(
96 route_id_
, has_pending_activity
));
99 void WebSharedWorkerClientProxy::reportPendingActivity(
100 bool has_pending_activity
) {
101 Send(new WorkerHostMsg_ReportPendingActivity(
102 route_id_
, has_pending_activity
));
105 void WebSharedWorkerClientProxy::workerContextClosed() {
106 Send(new WorkerHostMsg_WorkerContextClosed(route_id_
));
109 void WebSharedWorkerClientProxy::workerContextDestroyed() {
110 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_
));
111 // Tell the stub that the worker has shutdown - frees this object.
116 WebKit::WebNotificationPresenter
*
117 WebSharedWorkerClientProxy::notificationPresenter() {
118 // TODO(johnnyg): Notifications are not yet hooked up to workers.
124 WebApplicationCacheHost
* WebSharedWorkerClientProxy::createApplicationCacheHost(
125 WebKit::WebApplicationCacheHostClient
* client
) {
126 WorkerWebApplicationCacheHostImpl
* host
=
127 new WorkerWebApplicationCacheHostImpl(stub_
->appcache_init_info(),
129 // Remember the id of the instance we create so we have access to that
130 // value when creating nested dedicated workers in createWorker.
131 appcache_host_id_
= host
->host_id();
135 // TODO(abarth): Security checks should use WebDocument or WebSecurityOrigin,
136 // not WebFrame as the context object because WebFrames can contain different
137 // WebDocuments at different times.
138 bool WebSharedWorkerClientProxy::allowDatabase(WebFrame
* frame
,
139 const WebString
& name
,
140 const WebString
& display_name
,
141 unsigned long estimated_size
) {
142 WebSecurityOrigin origin
= frame
->document().securityOrigin();
143 if (origin
.isUnique())
147 Send(new WorkerProcessHostMsg_AllowDatabase(
148 route_id_
, GURL(origin
.toString().utf8()), name
, display_name
,
149 estimated_size
, &result
));
153 bool WebSharedWorkerClientProxy::allowFileSystem() {
155 Send(new WorkerProcessHostMsg_AllowFileSystem(
156 route_id_
, stub_
->url().GetOrigin(), &result
));
160 bool WebSharedWorkerClientProxy::allowIndexedDB(const WebKit::WebString
& name
) {
162 Send(new WorkerProcessHostMsg_AllowIndexedDB(
163 route_id_
, stub_
->url().GetOrigin(), name
, &result
));
167 void WebSharedWorkerClientProxy::dispatchDevToolsMessage(
168 const WebString
& message
) {
170 devtools_agent_
->SendDevToolsMessage(message
);
173 void WebSharedWorkerClientProxy::saveDevToolsAgentState(
174 const WebKit::WebString
& state
) {
176 devtools_agent_
->SaveDevToolsAgentState(state
);
179 bool WebSharedWorkerClientProxy::Send(IPC::Message
* message
) {
180 return WorkerThread::current()->Send(message
);
183 void WebSharedWorkerClientProxy::EnsureWorkerContextTerminates() {
184 // This shuts down the process cleanly from the perspective of the browser
185 // process, and avoids the crashed worker infobar from appearing to the new
186 // page. It's ok to post several of theese, because the first executed task
187 // will exit the message loop and subsequent ones won't be executed.
188 base::MessageLoop::current()->PostDelayedTask(
190 base::Bind(&WebSharedWorkerClientProxy::workerContextDestroyed
,
191 weak_factory_
.GetWeakPtr()),
192 base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds
));
195 } // namespace content