summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordimich@google.com <dimich@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-16 00:37:09 +0000
committerdimich@google.com <dimich@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-16 00:37:09 +0000
commitf2330fe08ed5e92b52c6c90d2230fe678e07eb17 (patch)
tree20a25568b86dfe7c59a925f8ef9b273e449532e6
parent8b3833e7804b92c2a2fab6f91ba08367ab103bb0 (diff)
downloadchromium_src-f2330fe08ed5e92b52c6c90d2230fe678e07eb17.zip
chromium_src-f2330fe08ed5e92b52c6c90d2230fe678e07eb17.tar.gz
chromium_src-f2330fe08ed5e92b52c6c90d2230fe678e07eb17.tar.bz2
Make XHR work in Workers. Creates a 'shadow page' in a worker process to proxy the loading requests through.
BUG=4361 TEST=none Review URL: http://codereview.chromium.org/126070 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18465 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/common/child_thread.h6
-rw-r--r--chrome/renderer/renderer_glue.cc4
-rw-r--r--webkit/glue/webworker_impl.cc96
-rw-r--r--webkit/glue/webworker_impl.h7
4 files changed, 105 insertions, 8 deletions
diff --git a/chrome/common/child_thread.h b/chrome/common/child_thread.h
index f612c35..cc4abaa 100644
--- a/chrome/common/child_thread.h
+++ b/chrome/common/child_thread.h
@@ -34,6 +34,9 @@ class ChildThread : public IPC::Channel::Listener,
return resource_dispatcher_.get();
}
+ // Returns the one child thread.
+ static ChildThread* current();
+
protected:
friend class ChildProcess;
@@ -52,9 +55,6 @@ class ChildThread : public IPC::Channel::Listener,
virtual void OnControlMessageReceived(const IPC::Message& msg) { }
- // Returns the one child thread.
- static ChildThread* current();
-
IPC::SyncChannel* channel() { return channel_.get(); }
// Thread implementation.
diff --git a/chrome/renderer/renderer_glue.cc b/chrome/renderer/renderer_glue.cc
index be7893d..5f31444 100644
--- a/chrome/renderer/renderer_glue.cc
+++ b/chrome/renderer/renderer_glue.cc
@@ -225,7 +225,7 @@ ResourceLoaderBridge* ResourceLoaderBridge::Create(
ResourceType::Type resource_type,
int app_cache_context_id,
int routing_id) {
- ResourceDispatcher* dispatch = RenderThread::current()->resource_dispatcher();
+ ResourceDispatcher* dispatch = ChildThread::current()->resource_dispatcher();
return dispatch->CreateBridge(method, url, first_party_for_cookies, referrer,
frame_origin, main_frame_origin, headers,
load_flags, origin_pid, resource_type, 0,
@@ -236,7 +236,7 @@ void NotifyCacheStats() {
// Update the browser about our cache
// NOTE: Since this can be called from the plugin process, we might not have
// a RenderThread. Do nothing in that case.
- if (!IsPluginProcess())
+ if (RenderThread::current())
RenderThread::current()->InformHostOfCacheStatsLater();
}
diff --git a/webkit/glue/webworker_impl.cc b/webkit/glue/webworker_impl.cc
index bee7f44..1328dd6 100644
--- a/webkit/glue/webworker_impl.cc
+++ b/webkit/glue/webworker_impl.cc
@@ -10,6 +10,7 @@
#include "KURL.h"
#include "ScriptExecutionContext.h"
#include "SecurityOrigin.h"
+#include "SubstituteData.h"
#include "WorkerContext.h"
#include "WorkerThread.h"
#include <wtf/MainThread.h>
@@ -18,10 +19,16 @@
#undef LOG
#include "base/logging.h"
+#include "webkit/api/public/WebScreenInfo.h"
#include "webkit/api/public/WebString.h"
#include "webkit/api/public/WebURL.h"
#include "webkit/api/public/WebWorkerClient.h"
#include "webkit/glue/glue_util.h"
+#include "webkit/glue/webdatasource_impl.h"
+#include "webkit/glue/webframe_impl.h"
+#include "webkit/glue/webpreferences.h"
+#include "webkit/glue/webview.h"
+#include "webkit/glue/webview_delegate.h"
#include "webkit/glue/webworker_impl.h"
using WebKit::WebWorker;
@@ -31,6 +38,58 @@ using WebKit::WebURL;
#if ENABLE(WORKERS)
+// Dummy WebViewDelegate - we only need it in Worker process to load a
+// 'shadow page' which will initialize WebCore loader.
+class WorkerWebViewDelegate : public WebViewDelegate {
+ public:
+ WorkerWebViewDelegate() {}
+ virtual void AddRef() { }
+ virtual void Release() { }
+ virtual void Blur(WebWidget *webwidget) { }
+ virtual void CloseWidgetSoon(WebWidget *webwidget) { }
+ virtual void DidInvalidateRect(WebWidget *webwidget,
+ const WebKit::WebRect &rect) { }
+ virtual void DidMove(WebWidget *webwidget, const WebPluginGeometry &move) { }
+ virtual void DidScrollRect(WebWidget *webwidget, int dx, int dy,
+ const WebKit::WebRect &clip_rect) { }
+ virtual void Focus(WebWidget *webwidget) { }
+ virtual gfx::NativeViewId GetContainingView(WebWidget *webwidget) {
+ return gfx::NativeViewId();
+ }
+ virtual void GetRootWindowRect(WebWidget *webwidget,
+ WebKit::WebRect *rect) { }
+ virtual void GetRootWindowResizerRect(WebWidget *webwidget,
+ WebKit::WebRect *rect) { }
+ virtual WebKit::WebScreenInfo GetScreenInfo(WebWidget *webwidget) {
+ WebKit::WebScreenInfo info;
+ return info;
+ }
+ virtual void GetWindowRect(WebWidget *webwidget, WebKit::WebRect *rect) { }
+ virtual bool IsHidden(WebWidget *webwidget) { return true; }
+ virtual void RunModal(WebWidget *webwidget) { }
+ virtual void SetCursor(WebWidget *webwidget, const WebCursor &cursor) { }
+ virtual void SetWindowRect(WebWidget *webwidget,
+ const WebKit::WebRect &rect) { }
+ virtual void Show(WebWidget *webwidget, WindowOpenDisposition disposition) { }
+ virtual void ShowAsPopupWithItems(WebWidget *webwidget,
+ const WebKit::WebRect &bounds,
+ int item_height,
+ int selected_index,
+ const std::vector<WebMenuItem> &items) { }
+ // Tell the loader to load the data into the 'shadow page' synchronously,
+ // so we can grab the resulting Document right after load.
+ virtual void DidCreateDataSource(WebFrame* frame, WebDataSource* ds) {
+ static_cast<WebDataSourceImpl*>(ds)->setDeferMainResourceDataLoad(false);
+ }
+ // Lazy allocate and leak this instance.
+ static WorkerWebViewDelegate* worker_delegate() {
+ static WorkerWebViewDelegate* worker_delegate = new WorkerWebViewDelegate();
+ return worker_delegate;
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WorkerWebViewDelegate);
+};
+
namespace WebKit {
WebWorker* WebWorker::create(WebWorkerClient* client) {
@@ -56,11 +115,14 @@ void InitializeWebKitStaticValues() {
}
}
-WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client) : client_(client) {
+WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client)
+ : client_(client),
+ web_view_(NULL) {
InitializeWebKitStaticValues();
}
WebWorkerImpl::~WebWorkerImpl() {
+ web_view_->Close();
}
void WebWorkerImpl::PostMessageToWorkerContextTask(
@@ -81,6 +143,33 @@ void WebWorkerImpl::PostMessageToWorkerContextTask(
void WebWorkerImpl::startWorkerContext(const WebURL& script_url,
const WebString& user_agent,
const WebString& source_code) {
+ // Create 'shadow page'. This page is never displayed, it is used to proxy the
+ // loading requests from the worker context to the rest of WebKit and Chromium
+ // infrastructure.
+ DCHECK(!web_view_);
+ web_view_ = WebView::Create(WorkerWebViewDelegate::worker_delegate(),
+ WebPreferences());
+
+ WebFrameImpl* web_frame =
+ static_cast<WebFrameImpl*>(web_view_->GetMainFrame());
+
+ // Construct substitute data source for the 'shadow page'. We only need it
+ // to have same origin as the worker so the loading checks work correctly.
+ WebCore::CString content("Shadow page");
+ int len = static_cast<int>(content.length());
+ RefPtr<WebCore::SharedBuffer> buf(
+ WebCore::SharedBuffer::create(content.data(), len));
+ WebCore::SubstituteData subst_data(buf,
+ WebCore::String("text/html"),
+ WebCore::String("UTF-8"),
+ WebCore::KURL());
+ WebCore::ResourceRequest request(webkit_glue::GURLToKURL(script_url),
+ WebCore::CString());
+ web_frame->frame()->loader()->load(request, subst_data, false);
+
+ // This document will be used as 'loading context' for the worker.
+ loading_document_ = web_frame->frame()->document();
+
worker_thread_ = WebCore::WorkerThread::create(
webkit_glue::WebURLToKURL(script_url),
webkit_glue::WebStringToString(user_agent),
@@ -235,13 +324,14 @@ void WebWorkerImpl::workerContextDestroyed() {
void WebWorkerImpl::postTaskToLoader(
PassRefPtr<WebCore::ScriptExecutionContext::Task> task) {
- NOTIMPLEMENTED();
+ ASSERT(loading_document_->isDocument());
+ loading_document_->postTask(task);
}
void WebWorkerImpl::postTaskForModeToWorkerContext(
PassRefPtr<WebCore::ScriptExecutionContext::Task> task,
const WebCore::String& mode) {
- NOTIMPLEMENTED();
+ worker_thread_->runLoop().postTaskForMode(task, mode);
}
void WebWorkerImpl::WorkerContextDestroyedTask(
diff --git a/webkit/glue/webworker_impl.h b/webkit/glue/webworker_impl.h
index 8c87d48..db12c09 100644
--- a/webkit/glue/webworker_impl.h
+++ b/webkit/glue/webworker_impl.h
@@ -19,6 +19,8 @@ class Strng;
class WorkerThread;
};
+class WebView;
+
// This class is used by the worker process code to talk to the WebCore::Worker
// implementation. It can't use it directly since it uses WebKit types, so this
// class converts the data types. When the WebCore::Worker object wants to call
@@ -113,6 +115,11 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy,
WebWorkerImpl* this_ptr);
WebKit::WebWorkerClient* client_;
+
+ // 'shadow page' - created to proxy loading requests from the worker.
+ WTF::RefPtr<WebCore::ScriptExecutionContext> loading_document_;
+ WebView* web_view_;
+
WTF::RefPtr<WebCore::WorkerThread> worker_thread_;
DISALLOW_COPY_AND_ASSIGN(WebWorkerImpl);