OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 | 8 |
9 #include "GenericWorkerTask.h" | 9 #include "GenericWorkerTask.h" |
10 #include "KURL.h" | 10 #include "KURL.h" |
11 #include "ScriptExecutionContext.h" | 11 #include "ScriptExecutionContext.h" |
12 #include "SecurityOrigin.h" | 12 #include "SecurityOrigin.h" |
| 13 #include "SubstituteData.h" |
13 #include "WorkerContext.h" | 14 #include "WorkerContext.h" |
14 #include "WorkerThread.h" | 15 #include "WorkerThread.h" |
15 #include <wtf/MainThread.h> | 16 #include <wtf/MainThread.h> |
16 #include <wtf/Threading.h> | 17 #include <wtf/Threading.h> |
17 | 18 |
18 #undef LOG | 19 #undef LOG |
19 | 20 |
20 #include "base/logging.h" | 21 #include "base/logging.h" |
| 22 #include "webkit/api/public/WebScreenInfo.h" |
21 #include "webkit/api/public/WebString.h" | 23 #include "webkit/api/public/WebString.h" |
22 #include "webkit/api/public/WebURL.h" | 24 #include "webkit/api/public/WebURL.h" |
23 #include "webkit/api/public/WebWorkerClient.h" | 25 #include "webkit/api/public/WebWorkerClient.h" |
24 #include "webkit/glue/glue_util.h" | 26 #include "webkit/glue/glue_util.h" |
| 27 #include "webkit/glue/webdatasource_impl.h" |
| 28 #include "webkit/glue/webframe_impl.h" |
| 29 #include "webkit/glue/webpreferences.h" |
| 30 #include "webkit/glue/webview.h" |
| 31 #include "webkit/glue/webview_delegate.h" |
25 #include "webkit/glue/webworker_impl.h" | 32 #include "webkit/glue/webworker_impl.h" |
26 | 33 |
27 using WebKit::WebWorker; | 34 using WebKit::WebWorker; |
28 using WebKit::WebWorkerClient; | 35 using WebKit::WebWorkerClient; |
29 using WebKit::WebString; | 36 using WebKit::WebString; |
30 using WebKit::WebURL; | 37 using WebKit::WebURL; |
31 | 38 |
32 #if ENABLE(WORKERS) | 39 #if ENABLE(WORKERS) |
33 | 40 |
| 41 // Dummy WebViewDelegate - we only need it in Worker process to load a |
| 42 // 'shadow page' which will initialize WebCore loader. |
| 43 class WorkerWebViewDelegate : public WebViewDelegate { |
| 44 public: |
| 45 WorkerWebViewDelegate() {} |
| 46 virtual void AddRef() { } |
| 47 virtual void Release() { } |
| 48 virtual void Blur(WebWidget *webwidget) { } |
| 49 virtual void CloseWidgetSoon(WebWidget *webwidget) { } |
| 50 virtual void DidInvalidateRect(WebWidget *webwidget, |
| 51 const WebKit::WebRect &rect) { } |
| 52 virtual void DidMove(WebWidget *webwidget, const WebPluginGeometry &move) { } |
| 53 virtual void DidScrollRect(WebWidget *webwidget, int dx, int dy, |
| 54 const WebKit::WebRect &clip_rect) { } |
| 55 virtual void Focus(WebWidget *webwidget) { } |
| 56 virtual gfx::NativeViewId GetContainingView(WebWidget *webwidget) { |
| 57 return gfx::NativeViewId(); |
| 58 } |
| 59 virtual void GetRootWindowRect(WebWidget *webwidget, |
| 60 WebKit::WebRect *rect) { } |
| 61 virtual void GetRootWindowResizerRect(WebWidget *webwidget, |
| 62 WebKit::WebRect *rect) { } |
| 63 virtual WebKit::WebScreenInfo GetScreenInfo(WebWidget *webwidget) { |
| 64 WebKit::WebScreenInfo info; |
| 65 return info; |
| 66 } |
| 67 virtual void GetWindowRect(WebWidget *webwidget, WebKit::WebRect *rect) { } |
| 68 virtual bool IsHidden(WebWidget *webwidget) { return true; } |
| 69 virtual void RunModal(WebWidget *webwidget) { } |
| 70 virtual void SetCursor(WebWidget *webwidget, const WebCursor &cursor) { } |
| 71 virtual void SetWindowRect(WebWidget *webwidget, |
| 72 const WebKit::WebRect &rect) { } |
| 73 virtual void Show(WebWidget *webwidget, WindowOpenDisposition disposition) { } |
| 74 virtual void ShowAsPopupWithItems(WebWidget *webwidget, |
| 75 const WebKit::WebRect &bounds, |
| 76 int item_height, |
| 77 int selected_index, |
| 78 const std::vector<WebMenuItem> &items) { } |
| 79 // Tell the loader to load the data into the 'shadow page' synchronously, |
| 80 // so we can grab the resulting Document right after load. |
| 81 virtual void DidCreateDataSource(WebFrame* frame, WebDataSource* ds) { |
| 82 static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false); |
| 83 } |
| 84 // Lazy allocate and leak this instance. |
| 85 static WorkerWebViewDelegate* worker_delegate() { |
| 86 static WorkerWebViewDelegate* worker_delegate = new WorkerWebViewDelegate(); |
| 87 return worker_delegate; |
| 88 } |
| 89 private: |
| 90 DISALLOW_COPY_AND_ASSIGN(WorkerWebViewDelegate); |
| 91 }; |
| 92 |
34 namespace WebKit { | 93 namespace WebKit { |
35 | 94 |
36 WebWorker* WebWorker::create(WebWorkerClient* client) { | 95 WebWorker* WebWorker::create(WebWorkerClient* client) { |
37 return new WebWorkerImpl(client); | 96 return new WebWorkerImpl(client); |
38 } | 97 } |
39 | 98 |
40 } | 99 } |
41 | 100 |
42 // This function is called on the main thread to force to initialize some static | 101 // This function is called on the main thread to force to initialize some static |
43 // values used in WebKit before any worker thread is started. This is because in | 102 // values used in WebKit before any worker thread is started. This is because in |
44 // our worker processs, we do not run any WebKit code in main thread and thus | 103 // our worker processs, we do not run any WebKit code in main thread and thus |
45 // when multiple workers try to start at the same time, we might hit crash due | 104 // when multiple workers try to start at the same time, we might hit crash due |
46 // to contention for initializing static values. | 105 // to contention for initializing static values. |
47 void InitializeWebKitStaticValues() { | 106 void InitializeWebKitStaticValues() { |
48 static bool initialized = false; | 107 static bool initialized = false; |
49 if (!initialized) { | 108 if (!initialized) { |
50 initialized= true; | 109 initialized= true; |
51 // Note that we have to pass a URL with valid protocol in order to follow | 110 // Note that we have to pass a URL with valid protocol in order to follow |
52 // the path to do static value initializations. | 111 // the path to do static value initializations. |
53 WTF::RefPtr<WebCore::SecurityOrigin> origin = | 112 WTF::RefPtr<WebCore::SecurityOrigin> origin = |
54 WebCore::SecurityOrigin::create(WebCore::KURL("http://localhost")); | 113 WebCore::SecurityOrigin::create(WebCore::KURL("http://localhost")); |
55 origin.release(); | 114 origin.release(); |
56 } | 115 } |
57 } | 116 } |
58 | 117 |
59 WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client) : client_(client) { | 118 WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client) |
| 119 : client_(client), |
| 120 web_view_(NULL) { |
60 InitializeWebKitStaticValues(); | 121 InitializeWebKitStaticValues(); |
61 } | 122 } |
62 | 123 |
63 WebWorkerImpl::~WebWorkerImpl() { | 124 WebWorkerImpl::~WebWorkerImpl() { |
| 125 web_view_->Close(); |
64 } | 126 } |
65 | 127 |
66 void WebWorkerImpl::PostMessageToWorkerContextTask( | 128 void WebWorkerImpl::PostMessageToWorkerContextTask( |
67 WebCore::ScriptExecutionContext* context, | 129 WebCore::ScriptExecutionContext* context, |
68 WebWorkerImpl* this_ptr, | 130 WebWorkerImpl* this_ptr, |
69 const WebCore::String& message) { | 131 const WebCore::String& message) { |
70 DCHECK(context->isWorkerContext()); | 132 DCHECK(context->isWorkerContext()); |
71 WebCore::WorkerContext* worker_context = | 133 WebCore::WorkerContext* worker_context = |
72 static_cast<WebCore::WorkerContext*>(context); | 134 static_cast<WebCore::WorkerContext*>(context); |
73 worker_context->dispatchMessage(message); | 135 worker_context->dispatchMessage(message); |
74 | 136 |
75 this_ptr->confirmMessageFromWorkerObject( | 137 this_ptr->confirmMessageFromWorkerObject( |
76 worker_context->hasPendingActivity()); | 138 worker_context->hasPendingActivity()); |
77 } | 139 } |
78 | 140 |
79 // WebWorker ------------------------------------------------------------------- | 141 // WebWorker ------------------------------------------------------------------- |
80 | 142 |
81 void WebWorkerImpl::startWorkerContext(const WebURL& script_url, | 143 void WebWorkerImpl::startWorkerContext(const WebURL& script_url, |
82 const WebString& user_agent, | 144 const WebString& user_agent, |
83 const WebString& source_code) { | 145 const WebString& source_code) { |
| 146 // Create 'shadow page'. This page is never displayed, it is used to proxy the |
| 147 // loading requests from the worker context to the rest of WebKit and Chromium |
| 148 // infrastructure. |
| 149 DCHECK(!web_view_); |
| 150 web_view_ = WebView::Create(WorkerWebViewDelegate::worker_delegate(), |
| 151 WebPreferences()); |
| 152 |
| 153 WebFrameImpl* web_frame = |
| 154 static_cast<WebFrameImpl*>(web_view_->GetMainFrame()); |
| 155 |
| 156 // Construct substitute data source for the 'shadow page'. We only need it |
| 157 // to have same origin as the worker so the loading checks work correctly. |
| 158 WebCore::CString content("Shadow page"); |
| 159 int len = static_cast<int>(content.length()); |
| 160 RefPtr<WebCore::SharedBuffer> buf( |
| 161 WebCore::SharedBuffer::create(content.data(), len)); |
| 162 WebCore::SubstituteData subst_data(buf, |
| 163 WebCore::String("text/html"), |
| 164 WebCore::String("UTF-8"), |
| 165 WebCore::KURL()); |
| 166 WebCore::ResourceRequest request(webkit_glue::GURLToKURL(script_url), |
| 167 WebCore::CString()); |
| 168 web_frame->frame()->loader()->load(request, subst_data, false); |
| 169 |
| 170 // This document will be used as 'loading context' for the worker. |
| 171 loading_document_ = web_frame->frame()->document(); |
| 172 |
84 worker_thread_ = WebCore::WorkerThread::create( | 173 worker_thread_ = WebCore::WorkerThread::create( |
85 webkit_glue::WebURLToKURL(script_url), | 174 webkit_glue::WebURLToKURL(script_url), |
86 webkit_glue::WebStringToString(user_agent), | 175 webkit_glue::WebStringToString(user_agent), |
87 webkit_glue::WebStringToString(source_code), | 176 webkit_glue::WebStringToString(source_code), |
88 *this, | 177 *this, |
89 *this); | 178 *this); |
90 | 179 |
91 // Worker initialization means a pending activity. | 180 // Worker initialization means a pending activity. |
92 reportPendingActivity(true); | 181 reportPendingActivity(true); |
93 | 182 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 void WebWorkerImpl::workerContextDestroyed() { | 317 void WebWorkerImpl::workerContextDestroyed() { |
229 DispatchTaskToMainThread(WebCore::createCallbackTask( | 318 DispatchTaskToMainThread(WebCore::createCallbackTask( |
230 &WorkerContextDestroyedTask, | 319 &WorkerContextDestroyedTask, |
231 this)); | 320 this)); |
232 } | 321 } |
233 | 322 |
234 // WorkerLoaderProxy ----------------------------------------------------------- | 323 // WorkerLoaderProxy ----------------------------------------------------------- |
235 | 324 |
236 void WebWorkerImpl::postTaskToLoader( | 325 void WebWorkerImpl::postTaskToLoader( |
237 PassRefPtr<WebCore::ScriptExecutionContext::Task> task) { | 326 PassRefPtr<WebCore::ScriptExecutionContext::Task> task) { |
238 NOTIMPLEMENTED(); | 327 ASSERT(loading_document_->isDocument()); |
| 328 loading_document_->postTask(task); |
239 } | 329 } |
240 | 330 |
241 void WebWorkerImpl::postTaskForModeToWorkerContext( | 331 void WebWorkerImpl::postTaskForModeToWorkerContext( |
242 PassRefPtr<WebCore::ScriptExecutionContext::Task> task, | 332 PassRefPtr<WebCore::ScriptExecutionContext::Task> task, |
243 const WebCore::String& mode) { | 333 const WebCore::String& mode) { |
244 NOTIMPLEMENTED(); | 334 worker_thread_->runLoop().postTaskForMode(task, mode); |
245 } | 335 } |
246 | 336 |
247 void WebWorkerImpl::WorkerContextDestroyedTask( | 337 void WebWorkerImpl::WorkerContextDestroyedTask( |
248 WebCore::ScriptExecutionContext* context, | 338 WebCore::ScriptExecutionContext* context, |
249 WebWorkerImpl* this_ptr) { | 339 WebWorkerImpl* this_ptr) { |
250 this_ptr->client_->workerContextDestroyed(); | 340 this_ptr->client_->workerContextDestroyed(); |
251 | 341 |
252 // The lifetime of this proxy is controlled by the worker context. | 342 // The lifetime of this proxy is controlled by the worker context. |
253 delete this_ptr; | 343 delete this_ptr; |
254 } | 344 } |
255 | 345 |
256 #else | 346 #else |
257 | 347 |
258 namespace WebKit { | 348 namespace WebKit { |
259 | 349 |
260 WebWorker* WebWorker::create(WebWorkerClient* client) { | 350 WebWorker* WebWorker::create(WebWorkerClient* client) { |
261 return NULL; | 351 return NULL; |
262 } | 352 } |
263 | 353 |
264 } | 354 } |
265 | 355 |
266 #endif | 356 #endif |
OLD | NEW |