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/shared_worker_devtools_agent.h"
11 #include "content/child/webmessageportchannel_impl.h"
12 #include "content/common/worker_messages.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/worker/shared_worker_permission_client_proxy.h"
15 #include "content/worker/websharedworker_stub.h"
16 #include "content/worker/worker_thread.h"
17 #include "content/worker/worker_webapplicationcachehost_impl.h"
18 #include "ipc/ipc_logging.h"
19 #include "third_party/WebKit/public/platform/WebString.h"
20 #include "third_party/WebKit/public/platform/WebURL.h"
21 #include "third_party/WebKit/public/web/WebDocument.h"
22 #include "third_party/WebKit/public/web/WebFrame.h"
23 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
25 using blink::WebApplicationCacheHost
;
26 using blink::WebFrame
;
27 using blink::WebMessagePortChannel
;
28 using blink::WebMessagePortChannelArray
;
29 using blink::WebSecurityOrigin
;
30 using blink::WebString
;
31 using blink::WebWorker
;
32 using blink::WebSharedWorkerClient
;
36 // How long to wait for worker to finish after it's been told to terminate.
37 #define kMaxTimeForRunawayWorkerSeconds 3
39 WebSharedWorkerClientProxy::WebSharedWorkerClientProxy(
40 int route_id
, WebSharedWorkerStub
* stub
)
41 : route_id_(route_id
),
45 devtools_agent_(NULL
),
46 app_cache_host_(NULL
) {
49 WebSharedWorkerClientProxy::~WebSharedWorkerClientProxy() {
52 void WebSharedWorkerClientProxy::workerContextClosed() {
53 Send(new WorkerHostMsg_WorkerContextClosed(route_id_
));
56 void WebSharedWorkerClientProxy::workerContextDestroyed() {
57 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_
));
58 // Tell the stub that the worker has shutdown - frees this object.
63 void WebSharedWorkerClientProxy::workerScriptLoaded() {
64 Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_
));
66 stub_
->WorkerScriptLoaded();
69 void WebSharedWorkerClientProxy::workerScriptLoadFailed() {
70 Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_
));
72 stub_
->WorkerScriptLoadFailed();
75 void WebSharedWorkerClientProxy::selectAppCacheID(long long app_cache_id
) {
76 if (app_cache_host_
) {
77 // app_cache_host_ could become stale as it's owned by blink's
78 // DocumentLoader. This method is assumed to be called while it's valid.
79 app_cache_host_
->backend()->SelectCacheForSharedWorker(
80 app_cache_host_
->host_id(),
85 blink::WebNotificationPresenter
*
86 WebSharedWorkerClientProxy::notificationPresenter() {
87 // TODO(johnnyg): Notifications are not yet hooked up to workers.
93 WebApplicationCacheHost
* WebSharedWorkerClientProxy::createApplicationCacheHost(
94 blink::WebApplicationCacheHostClient
* client
) {
95 DCHECK(!app_cache_host_
);
96 app_cache_host_
= new WorkerWebApplicationCacheHostImpl(client
);
97 // Remember the id of the instance we create so we have access to that
98 // value when creating nested dedicated workers in createWorker.
99 appcache_host_id_
= app_cache_host_
->host_id();
100 return app_cache_host_
;
103 blink::WebWorkerPermissionClientProxy
*
104 WebSharedWorkerClientProxy::createWorkerPermissionClientProxy(
105 const blink::WebSecurityOrigin
& origin
) {
106 return new SharedWorkerPermissionClientProxy(
107 GURL(origin
.toString()), origin
.isUnique(), route_id_
,
108 ChildThread::current()->thread_safe_sender());
111 void WebSharedWorkerClientProxy::dispatchDevToolsMessage(
112 const WebString
& message
) {
114 devtools_agent_
->SendDevToolsMessage(message
);
117 void WebSharedWorkerClientProxy::saveDevToolsAgentState(
118 const blink::WebString
& state
) {
120 devtools_agent_
->SaveDevToolsAgentState(state
);
123 bool WebSharedWorkerClientProxy::Send(IPC::Message
* message
) {
124 return WorkerThread::current()->Send(message
);
127 void WebSharedWorkerClientProxy::EnsureWorkerContextTerminates() {
128 // This shuts down the process cleanly from the perspective of the browser
129 // process, and avoids the crashed worker infobar from appearing to the new
130 // page. It's ok to post several of theese, because the first executed task
131 // will exit the message loop and subsequent ones won't be executed.
132 base::MessageLoop::current()->PostDelayedTask(
134 base::Bind(&WebSharedWorkerClientProxy::workerContextDestroyed
,
135 weak_factory_
.GetWeakPtr()),
136 base::TimeDelta::FromSeconds(kMaxTimeForRunawayWorkerSeconds
));
139 } // namespace content