tizen beta release
[framework/web/webkit-efl.git] / Source / WebKit / chromium / src / WebSharedWorkerImpl.cpp
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "WebSharedWorkerImpl.h"
33
34 #include "CrossThreadTask.h"
35 #include "KURL.h"
36 #include "MessageEvent.h"
37 #include "MessagePortChannel.h"
38 #include "PlatformMessagePortChannel.h"
39 #include "ScriptExecutionContext.h"
40 #include "SharedWorkerContext.h"
41 #include "SharedWorkerThread.h"
42 #include "WorkerDebuggerAgent.h"
43 #include "WorkerInspectorController.h"
44
45 #include "WebMessagePortChannel.h"
46 #include "WebString.h"
47 #include "WebURL.h"
48
49 using namespace WebCore;
50
51 namespace WebKit {
52
53 #if ENABLE(SHARED_WORKERS)
54
55 WebSharedWorkerImpl::WebSharedWorkerImpl(WebCommonWorkerClient* client)
56     : m_client(client)
57     , m_pauseWorkerContextOnStart(false)
58 {
59 }
60
61 WebSharedWorkerImpl::~WebSharedWorkerImpl()
62 {
63 }
64
65 bool WebSharedWorkerImpl::isStarted()
66 {
67     // Should not ever be called from the worker thread (this API is only called on WebSharedWorkerProxy on the renderer thread).
68     ASSERT_NOT_REACHED();
69     return workerThread();
70 }
71
72 void WebSharedWorkerImpl::connect(WebMessagePortChannel* webChannel, ConnectListener* listener)
73 {
74     // Convert the WebMessagePortChanel to a WebCore::MessagePortChannel.
75     RefPtr<PlatformMessagePortChannel> platform_channel =
76         PlatformMessagePortChannel::create(webChannel);
77     webChannel->setClient(platform_channel.get());
78     OwnPtr<MessagePortChannel> channel =
79         MessagePortChannel::create(platform_channel);
80
81     workerThread()->runLoop().postTask(
82         createCallbackTask(&connectTask, channel.release()));
83     if (listener)
84         listener->connected();
85 }
86
87 void WebSharedWorkerImpl::connectTask(ScriptExecutionContext* context, PassOwnPtr<MessagePortChannel> channel)
88 {
89     // Wrap the passed-in channel in a MessagePort, and send it off via a connect event.
90     RefPtr<MessagePort> port = MessagePort::create(*context);
91     port->entangle(channel);
92     ASSERT(context->isWorkerContext());
93     WorkerContext* workerContext = static_cast<WorkerContext*>(context);
94     ASSERT(workerContext->isSharedWorkerContext());
95     workerContext->dispatchEvent(createConnectEvent(port));
96 }
97
98 void WebSharedWorkerImpl::startWorkerContext(const WebURL& url, const WebString& name, const WebString& userAgent, const WebString& sourceCode, long long)
99 {
100     initializeLoader(url);
101     WorkerThreadStartMode startMode = m_pauseWorkerContextOnStart ? PauseWorkerContextOnStart : DontPauseWorkerContextOnStart;
102     setWorkerThread(SharedWorkerThread::create(name, url, userAgent, sourceCode, *this, *this, startMode));
103     workerThread()->start();
104 }
105
106 void WebSharedWorkerImpl::terminateWorkerContext()
107 {
108     stopWorkerThread();
109 }
110
111 void WebSharedWorkerImpl::clientDestroyed()
112 {
113     m_client = 0;
114 }
115
116 void WebSharedWorkerImpl::pauseWorkerContextOnStart()
117 {
118     m_pauseWorkerContextOnStart = true;
119 }
120
121 static void resumeWorkerContextTask(ScriptExecutionContext* context, bool)
122 {
123     ASSERT(context->isWorkerContext());
124     static_cast<WorkerContext*>(context)->workerInspectorController()->resume();
125 }
126
127 void WebSharedWorkerImpl::resumeWorkerContext()
128 {
129     m_pauseWorkerContextOnStart = false;
130     if (workerThread())
131         workerThread()->runLoop().postTaskForMode(createCallbackTask(resumeWorkerContextTask, true), WorkerDebuggerAgent::debuggerTaskMode);
132 }
133
134 static void connectToWorkerContextInspectorTask(ScriptExecutionContext* context, bool)
135 {
136     ASSERT(context->isWorkerContext());
137     static_cast<WorkerContext*>(context)->workerInspectorController()->connectFrontend();
138 }
139
140 void WebSharedWorkerImpl::attachDevTools()
141 {
142     workerThread()->runLoop().postTaskForMode(createCallbackTask(connectToWorkerContextInspectorTask, true), WorkerDebuggerAgent::debuggerTaskMode);
143 }
144
145 static void reconnectToWorkerContextInspectorTask(ScriptExecutionContext* context, const String& savedState)
146 {
147     ASSERT(context->isWorkerContext());
148     WorkerInspectorController* ic = static_cast<WorkerContext*>(context)->workerInspectorController();
149     ic->restoreInspectorStateFromCookie(savedState);
150     ic->resume();
151 }
152
153 void WebSharedWorkerImpl::reattachDevTools(const WebString& savedState)
154 {
155     workerThread()->runLoop().postTaskForMode(createCallbackTask(reconnectToWorkerContextInspectorTask, String(savedState)), WorkerDebuggerAgent::debuggerTaskMode);
156 }
157
158 static void disconnectFromWorkerContextInspectorTask(ScriptExecutionContext* context, bool)
159 {
160     ASSERT(context->isWorkerContext());
161     static_cast<WorkerContext*>(context)->workerInspectorController()->disconnectFrontend();
162 }
163
164 void WebSharedWorkerImpl::detachDevTools()
165 {
166     workerThread()->runLoop().postTaskForMode(createCallbackTask(disconnectFromWorkerContextInspectorTask, true), WorkerDebuggerAgent::debuggerTaskMode);
167 }
168
169 static void dispatchOnInspectorBackendTask(ScriptExecutionContext* context, const String& message)
170 {
171     ASSERT(context->isWorkerContext());
172     static_cast<WorkerContext*>(context)->workerInspectorController()->dispatchMessageFromFrontend(message);
173 }
174
175 void WebSharedWorkerImpl::dispatchDevToolsMessage(const WebString& message)
176 {
177     workerThread()->runLoop().postTaskForMode(createCallbackTask(dispatchOnInspectorBackendTask, String(message)), WorkerDebuggerAgent::debuggerTaskMode);
178 }
179
180 WebWorkerClient* WebSharedWorkerImpl::client()
181 {
182     // We should never be asked for a WebWorkerClient (only dedicated workers have an associated WebWorkerClient).
183     // It should not be possible for SharedWorkerContext to generate an API call outside those supported by WebCommonWorkerClient.
184     ASSERT_NOT_REACHED();
185     return 0;
186 }
187
188 WebSharedWorker* WebSharedWorker::create(WebCommonWorkerClient* client)
189 {
190     return new WebSharedWorkerImpl(client);
191 }
192
193 #endif // ENABLE(SHARED_WORKERS)
194
195 } // namespace WebKit