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.h"
10 #include "content/common/fileapi/file_system_dispatcher.h"
11 #include "content/common/fileapi/webfilesystem_callback_dispatcher.h"
12 #include "content/common/webmessageportchannel_impl.h"
13 #include "content/common/worker_messages.h"
14 #include "content/public/common/content_switches.h"
15 #include "content/worker/shared_worker_devtools_agent.h"
16 #include "content/worker/websharedworker_stub.h"
17 #include "content/worker/worker_thread.h"
18 #include "content/worker/worker_webapplicationcachehost_impl.h"
19 #include "ipc/ipc_logging.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystemCallbacks.h"
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
27 using WebKit::WebApplicationCacheHost
;
28 using WebKit::WebFrame
;
29 using WebKit::WebMessagePortChannel
;
30 using WebKit::WebMessagePortChannelArray
;
31 using WebKit::WebSecurityOrigin
;
32 using WebKit::WebString
;
33 using WebKit::WebWorker
;
34 using WebKit::WebSharedWorkerClient
;
38 // How long to wait for worker to finish after it's been told to terminate.
39 #define kMaxTimeForRunawayWorkerSeconds 3
41 WebSharedWorkerClientProxy::WebSharedWorkerClientProxy(
42 int route_id
, WebSharedWorkerStub
* stub
)
43 : route_id_(route_id
),
46 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
47 devtools_agent_(NULL
) {
50 WebSharedWorkerClientProxy::~WebSharedWorkerClientProxy() {
53 void WebSharedWorkerClientProxy::postMessageToWorkerObject(
54 const WebString
& message
,
55 const WebMessagePortChannelArray
& channels
) {
56 std::vector
<int> message_port_ids(channels
.size());
57 std::vector
<int> routing_ids(channels
.size());
58 for (size_t i
= 0; i
< channels
.size(); ++i
) {
59 WebMessagePortChannelImpl
* webchannel
=
60 static_cast<WebMessagePortChannelImpl
*>(channels
[i
]);
61 message_port_ids
[i
] = webchannel
->message_port_id();
62 webchannel
->QueueMessages();
63 DCHECK(message_port_ids
[i
] != MSG_ROUTING_NONE
);
64 routing_ids
[i
] = MSG_ROUTING_NONE
;
67 Send(new WorkerMsg_PostMessage(
68 route_id_
, message
, message_port_ids
, routing_ids
));
71 void WebSharedWorkerClientProxy::postExceptionToWorkerObject(
72 const WebString
& error_message
,
74 const WebString
& source_url
) {
75 Send(new WorkerHostMsg_PostExceptionToWorkerObject(
76 route_id_
, error_message
, line_number
, source_url
));
79 void WebSharedWorkerClientProxy::postConsoleMessageToWorkerObject(
83 const WebString
& message
,
85 const WebString
& source_url
) {
86 WorkerHostMsg_PostConsoleMessageToWorkerObject_Params params
;
87 params
.source_identifier
= source
;
88 params
.message_type
= type
;
89 params
.message_level
= level
;
90 params
.message
= message
;
91 params
.line_number
= line_number
;
92 params
.source_url
= source_url
;
93 Send(new WorkerHostMsg_PostConsoleMessageToWorkerObject(route_id_
, params
));
96 void WebSharedWorkerClientProxy::confirmMessageFromWorkerObject(
97 bool has_pending_activity
) {
98 Send(new WorkerHostMsg_ConfirmMessageFromWorkerObject(
99 route_id_
, has_pending_activity
));
102 void WebSharedWorkerClientProxy::reportPendingActivity(
103 bool has_pending_activity
) {
104 Send(new WorkerHostMsg_ReportPendingActivity(
105 route_id_
, has_pending_activity
));
108 void WebSharedWorkerClientProxy::workerContextClosed() {
109 Send(new WorkerHostMsg_WorkerContextClosed(route_id_
));
112 void WebSharedWorkerClientProxy::workerContextDestroyed() {
113 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_
));
114 // Tell the stub that the worker has shutdown - frees this object.
119 WebKit::WebNotificationPresenter
*
120 WebSharedWorkerClientProxy::notificationPresenter() {
121 // TODO(johnnyg): Notifications are not yet hooked up to workers.
127 WebApplicationCacheHost
* WebSharedWorkerClientProxy::createApplicationCacheHost(
128 WebKit::WebApplicationCacheHostClient
* client
) {
129 WorkerWebApplicationCacheHostImpl
* host
=
130 new WorkerWebApplicationCacheHostImpl(stub_
->appcache_init_info(),
132 // Remember the id of the instance we create so we have access to that
133 // value when creating nested dedicated workers in createWorker.
134 appcache_host_id_
= host
->host_id();
138 // TODO(abarth): Security checks should use WebDocument or WebSecurityOrigin,
139 // not WebFrame as the context object because WebFrames can contain different
140 // WebDocuments at different times.
141 bool WebSharedWorkerClientProxy::allowDatabase(WebFrame
* frame
,
142 const WebString
& name
,
143 const WebString
& display_name
,
144 unsigned long estimated_size
) {
145 WebSecurityOrigin origin
= frame
->document().securityOrigin();
146 if (origin
.isUnique())
150 Send(new WorkerProcessHostMsg_AllowDatabase(
151 route_id_
, GURL(origin
.toString().utf8()), name
, display_name
,
152 estimated_size
, &result
));
156 bool WebSharedWorkerClientProxy::allowFileSystem() {
158 Send(new WorkerProcessHostMsg_AllowFileSystem(
159 route_id_
, stub_
->url().GetOrigin(), &result
));
163 void WebSharedWorkerClientProxy::openFileSystem(
164 WebKit::WebFileSystem::Type type
,
167 WebKit::WebFileSystemCallbacks
* callbacks
) {
168 ChildThread::current()->file_system_dispatcher()->OpenFileSystem(
169 stub_
->url().GetOrigin(), static_cast<fileapi::FileSystemType
>(type
),
170 size
, create
, new WebFileSystemCallbackDispatcher(callbacks
));
173 bool WebSharedWorkerClientProxy::allowIndexedDB(const WebKit::WebString
& name
) {
175 Send(new WorkerProcessHostMsg_AllowIndexedDB(
176 route_id_
, stub_
->url().GetOrigin(), name
, &result
));
180 void WebSharedWorkerClientProxy::dispatchDevToolsMessage(
181 const WebString
& message
) {
183 devtools_agent_
->SendDevToolsMessage(message
);
186 void WebSharedWorkerClientProxy::saveDevToolsAgentState(
187 const WebKit::WebString
& state
) {
189 devtools_agent_
->SaveDevToolsAgentState(state
);
192 bool WebSharedWorkerClientProxy::Send(IPC::Message
* message
) {
193 return WorkerThread::current()->Send(message
);
196 void WebSharedWorkerClientProxy::EnsureWorkerContextTerminates() {
197 // This shuts down the process cleanly from the perspective of the browser
198 // process, and avoids the crashed worker infobar from appearing to the new
199 // page. It's ok to post several of theese, because the first executed task
200 // will exit the message loop and subsequent ones won't be executed.
201 MessageLoop::current()->PostDelayedTask(FROM_HERE
,
203 &WebSharedWorkerClientProxy::workerContextDestroyed
,
204 weak_factory_
.GetWeakPtr()),
205 base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds
));
208 } // namespace content