Diff
Modified: trunk/Source/WebKit/chromium/ChangeLog (146632 => 146633)
--- trunk/Source/WebKit/chromium/ChangeLog 2013-03-22 18:13:36 UTC (rev 146632)
+++ trunk/Source/WebKit/chromium/ChangeLog 2013-03-22 18:27:02 UTC (rev 146633)
@@ -1,3 +1,56 @@
+2013-03-22 Alec Flett <alecfl...@chromium.org>
+
+ [chromium] Support Quota API in Worker
+ https://bugs.webkit.org/show_bug.cgi?id=112713
+
+ Hook up WebKit side of queryUsageAndQuota. Tests
+ and WebCore code will come in https://bugs.webkit.org/show_bug.cgi?id=112972
+
+ Reviewed by David Levin.
+
+ * WebKit.gyp:
+ * public/WebCommonWorkerClient.h:
+ (WebKit::WebCommonWorkerClient::queryUsageAndQuota):
+ * src/StorageQuotaChromium.cpp:
+ (WebCore::StorageQuota::queryUsageAndQuota):
+ (WebCore::StorageQuota::requestQuota):
+ * src/WebWorkerClientImpl.cpp:
+ (WebKit::WebWorkerClientImpl::queryUsageAndQuota):
+ (WebKit):
+ * src/WebWorkerClientImpl.h:
+ * src/WorkerStorageQuotaCallbacksBridge.cpp: Added.
+ (WebKit):
+ (MainThreadStorageQuotaCallbacks):
+ (WebKit::MainThreadStorageQuotaCallbacks::createLeakedPtr):
+ (WebKit::MainThreadStorageQuotaCallbacks::~MainThreadStorageQuotaCallbacks):
+ (WebKit::MainThreadStorageQuotaCallbacks::didQueryStorageUsageAndQuota):
+ (WebKit::MainThreadStorageQuotaCallbacks::didFail):
+ (WebKit::MainThreadStorageQuotaCallbacks::didGrantStorageQuota):
+ (WebKit::MainThreadStorageQuotaCallbacks::MainThreadStorageQuotaCallbacks):
+ (WorkerStorageQuotaContextObserver):
+ (WebKit::WorkerStorageQuotaContextObserver::create):
+ (WebKit::WorkerStorageQuotaContextObserver::notifyStop):
+ (WebKit::WorkerStorageQuotaContextObserver::WorkerStorageQuotaContextObserver):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::stop):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::cleanUpAfterCallback):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::WorkerStorageQuotaCallbacksBridge):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::~WorkerStorageQuotaCallbacksBridge):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::postQueryUsageAndQuotaToMainThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::queryUsageAndQuotaOnMainThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::didFailOnMainThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::didQueryStorageUsageAndQuotaOnMainThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::didFailOnWorkerThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::didQueryStorageUsageAndQuotaOnWorkerThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::runTaskOnMainThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::runTaskOnWorkerThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::dispatchTaskToMainThread):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::mayPostTaskToWorker):
+ * src/WorkerStorageQuotaCallbacksBridge.h: Added.
+ (WebCore):
+ (WebKit):
+ (WorkerStorageQuotaCallbacksBridge):
+ (WebKit::WorkerStorageQuotaCallbacksBridge::create):
+
2013-03-22 Stephen Chenney <schen...@chromium.org>
Skia flag removal to enable bug fixes and performance improvements.
Modified: trunk/Source/WebKit/chromium/WebKit.gyp (146632 => 146633)
--- trunk/Source/WebKit/chromium/WebKit.gyp 2013-03-22 18:13:36 UTC (rev 146632)
+++ trunk/Source/WebKit/chromium/WebKit.gyp 2013-03-22 18:27:02 UTC (rev 146633)
@@ -260,6 +260,7 @@
'public/WebStorageEventDispatcher.h',
'public/WebStorageQuotaCallbacks.h',
'public/WebStorageQuotaType.h',
+ 'public/WebStorageQuotaError.h',
'public/WebSurroundingText.h',
'public/WebStreamTextureClient.h',
'public/WebTextAffinity.h',
@@ -595,6 +596,8 @@
'src/WorkerFileSystemCallbacksBridge.h',
'src/WorkerFileWriterCallbacksBridge.cpp',
'src/WorkerFileWriterCallbacksBridge.h',
+ 'src/WorkerStorageQuotaCallbacksBridge.cpp',
+ 'src/WorkerStorageQuotaCallbacksBridge.h',
'src/win/WebInputEventFactory.cpp',
'src/win/WebScreenInfoFactory.cpp',
],
Modified: trunk/Source/WebKit/chromium/public/WebCommonWorkerClient.h (146632 => 146633)
--- trunk/Source/WebKit/chromium/public/WebCommonWorkerClient.h 2013-03-22 18:13:36 UTC (rev 146632)
+++ trunk/Source/WebKit/chromium/public/WebCommonWorkerClient.h 2013-03-22 18:27:02 UTC (rev 146633)
@@ -34,6 +34,9 @@
#include "../../../Platform/chromium/public/WebCommon.h"
#include "../../../Platform/chromium/public/WebFileSystem.h"
#include "../../../Platform/chromium/public/WebFileSystemType.h"
+// FIXME: need to move this to Platform
+#include "WebStorageQuotaCallbacks.h"
+#include "WebStorageQuotaType.h"
namespace WebKit {
@@ -70,6 +73,10 @@
{
return true;
}
+ virtual void queryUsageAndQuota(WebStorageQuotaType, WebStorageQuotaCallbacks*)
+ {
+ WEBKIT_ASSERT_NOT_REACHED();
+ }
};
Modified: trunk/Source/WebKit/chromium/src/StorageQuotaChromium.cpp (146632 => 146633)
--- trunk/Source/WebKit/chromium/src/StorageQuotaChromium.cpp 2013-03-22 18:13:36 UTC (rev 146632)
+++ trunk/Source/WebKit/chromium/src/StorageQuotaChromium.cpp 2013-03-22 18:27:02 UTC (rev 146633)
@@ -43,11 +43,34 @@
#include "WebFrameImpl.h"
#include "WebStorageQuotaCallbacksImpl.h"
#include "WebStorageQuotaType.h"
+#include "WebWorkerBase.h"
+#include "WorkerContext.h"
+#include "WorkerStorageQuotaCallbacksBridge.h"
+#include "WorkerThread.h"
+#include <wtf/Threading.h>
using namespace WebKit;
namespace WebCore {
+#if ENABLE(WORKERS)
+
+static void queryUsageAndQuotaFromWorker(WebCommonWorkerClient* commonClient, WebStorageQuotaType storageType, WebStorageQuotaCallbacksImpl* callbacks)
+{
+ WorkerContext* workerContext = WorkerScriptController::controllerForContext()->workerContext();
+ WebCore::WorkerThread* workerThread = workerContext->thread();
+ WebCore::WorkerLoaderProxy* workerLoaderProxy = &workerThread->workerLoaderProxy();
+
+ String mode = "queryUsageAndQuotaMode" + String::number(workerThread->runLoop().createUniqueId());
+
+ RefPtr<WorkerStorageQuotaCallbacksBridge> bridge = WorkerStorageQuotaCallbacksBridge::create(workerLoaderProxy, workerContext, callbacks);
+
+ // The bridge is held by the task that is created in posted to the main thread by this method.
+ bridge->postQueryUsageAndQuotaToMainThread(commonClient, storageType, mode);
+}
+
+#endif // ENABLE(WORKERS)
+
void StorageQuota::queryUsageAndQuota(ScriptExecutionContext* scriptExecutionContext, PassRefPtr<StorageUsageCallback> successCallback, PassRefPtr<StorageErrorCallback> errorCallback)
{
ASSERT(scriptExecutionContext);
@@ -62,8 +85,13 @@
WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
webFrame->client()->queryStorageUsageAndQuota(webFrame, storageType, new WebStorageQuotaCallbacksImpl(successCallback, errorCallback));
} else {
- // FIXME: calling this on worker is not yet supported.
- scriptExecutionContext->postTask(StorageErrorCallback::CallbackTask::create(errorCallback, NOT_SUPPORTED_ERR));
+#if ENABLE(WORKERS)
+ WorkerContext* workerContext = static_cast<WorkerContext*>(scriptExecutionContext);
+ WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerContext->thread()->workerLoaderProxy().toWebWorkerBase());
+ queryUsageAndQuotaFromWorker(webWorker->commonClient(), storageType, new WebStorageQuotaCallbacksImpl(successCallback, errorCallback));
+#else
+ ASSERT_NOT_REACHED();
+#endif
}
}
@@ -81,7 +109,7 @@
WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
webFrame->client()->requestStorageQuota(webFrame, storageType, newQuotaInBytes, new WebStorageQuotaCallbacksImpl(successCallback, errorCallback));
} else {
- // FIXME: calling this on worker is not yet supported.
+ // Requesting quota in Worker is not supported.
scriptExecutionContext->postTask(StorageErrorCallback::CallbackTask::create(errorCallback, NOT_SUPPORTED_ERR));
}
}
Modified: trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.cpp (146632 => 146633)
--- trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.cpp 2013-03-22 18:13:36 UTC (rev 146632)
+++ trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.cpp 2013-03-22 18:27:02 UTC (rev 146633)
@@ -142,6 +142,15 @@
return !webView->permissionClient() || webView->permissionClient()->allowIndexedDB(m_webFrame, name, WebSecurityOrigin());
}
+void WebWorkerClientImpl::queryUsageAndQuota(WebStorageQuotaType type, WebStorageQuotaCallbacks* callbacks)
+{
+ if (askedToTerminate()) {
+ callbacks->didFail(WebStorageQuotaErrorAbort);
+ return;
+ }
+ m_webFrame->client()->queryStorageUsageAndQuota(m_webFrame, type, callbacks);
+}
+
WebWorkerClientImpl::WebWorkerClientImpl(Worker* worker, WebFrameImpl* webFrame)
: WebCore::WorkerMessagingProxy(worker)
, m_webFrame(webFrame)
Modified: trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.h (146632 => 146633)
--- trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.h 2013-03-22 18:13:36 UTC (rev 146632)
+++ trunk/Source/WebKit/chromium/src/WebWorkerClientImpl.h 2013-03-22 18:27:02 UTC (rev 146633)
@@ -87,6 +87,7 @@
virtual void openFileSystem(WebFileSystemType, long long size, bool create,
WebFileSystemCallbacks*) OVERRIDE;
virtual bool allowIndexedDB(const WebString& name) OVERRIDE;
+ virtual void queryUsageAndQuota(WebStorageQuotaType, WebStorageQuotaCallbacks*) OVERRIDE;
private:
WebWorkerClientImpl(WebCore::Worker*, WebFrameImpl*);
Added: trunk/Source/WebKit/chromium/src/WorkerStorageQuotaCallbacksBridge.cpp (0 => 146633)
--- trunk/Source/WebKit/chromium/src/WorkerStorageQuotaCallbacksBridge.cpp (rev 0)
+++ trunk/Source/WebKit/chromium/src/WorkerStorageQuotaCallbacksBridge.cpp 2013-03-22 18:27:02 UTC (rev 146633)
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WorkerStorageQuotaCallbacksBridge.h"
+
+#include "CrossThreadTask.h"
+#include "WebCommonWorkerClient.h"
+#include "WebStorageQuotaCallbacks.h"
+#include "WebStorageQuotaCallbacksImpl.h"
+#include "WebWorkerBase.h"
+#include "WorkerContext.h"
+#include "WorkerLoaderProxy.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+// FIXME: Replace WebFrame parameter in queryStorageUsageAndQuota() with WebString and move the method to Platform so that we can remove all these complexity for Worker.
+class MainThreadStorageQuotaCallbacks : public WebStorageQuotaCallbacks {
+public:
+ // Callbacks are self-destructed and we always return leaked pointer here.
+ static MainThreadStorageQuotaCallbacks* createLeakedPtr(PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge, const String& mode)
+ {
+ OwnPtr<MainThreadStorageQuotaCallbacks> callbacks = adoptPtr(new MainThreadStorageQuotaCallbacks(bridge, mode));
+ return callbacks.leakPtr();
+ }
+
+ virtual ~MainThreadStorageQuotaCallbacks()
+ {
+ }
+
+ virtual void didQueryStorageUsageAndQuota(unsigned long long usageInBytes, unsigned long long quotaInBytes)
+ {
+ m_bridge->didQueryStorageUsageAndQuotaOnMainThread(usageInBytes, quotaInBytes, m_mode);
+ delete this;
+ }
+
+ virtual void didFail(WebStorageQuotaError error)
+ {
+ m_bridge->didFailOnMainThread(error, m_mode);
+ delete this;
+ }
+
+ virtual void didGrantStorageQuota(unsigned long long grantedQuotaInBytes)
+ {
+ ASSERT_NOT_REACHED();
+ }
+
+private:
+ MainThreadStorageQuotaCallbacks(PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge, const String& mode)
+ : m_bridge(bridge)
+ , m_mode(mode)
+ {
+ ASSERT(m_bridge);
+ }
+
+ RefPtr<WorkerStorageQuotaCallbacksBridge> m_bridge;
+ const String m_mode;
+};
+
+// FIXME: Replace WebFrame parameter in queryStorageUsageAndQuota() with WebString and move the method to Platform so that we can remove all these complexity for Worker."
+// Observes the worker context. By keeping this separate, it is easier to verify
+// that it only gets deleted on the worker context thread which is verified by ~Observer.
+class WorkerStorageQuotaContextObserver : public WebCore::WorkerContext::Observer {
+public:
+ static PassOwnPtr<WorkerStorageQuotaContextObserver> create(WorkerContext* context, PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge)
+ {
+ return adoptPtr(new WorkerStorageQuotaContextObserver(context, bridge));
+ }
+
+ // WorkerContext::Observer method.
+ virtual void notifyStop()
+ {
+ m_bridge->stop();
+ }
+
+private:
+ WorkerStorageQuotaContextObserver(WorkerContext* context, PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge)
+ : WebCore::WorkerContext::Observer(context)
+ , m_bridge(bridge)
+ {
+ }
+
+ RefPtr<WorkerStorageQuotaCallbacksBridge> m_bridge;
+};
+
+void WorkerStorageQuotaCallbacksBridge::stop()
+{
+ ASSERT(m_workerContext->isContextThread());
+ {
+ MutexLocker locker(m_loaderProxyMutex);
+ m_workerLoaderProxy = 0;
+ }
+
+ if (m_callbacksOnWorkerThread)
+ m_callbacksOnWorkerThread->didFail(WebStorageQuotaErrorAbort);
+
+ cleanUpAfterCallback();
+}
+
+void WorkerStorageQuotaCallbacksBridge::cleanUpAfterCallback()
+{
+ ASSERT(m_workerContext->isContextThread());
+
+ m_callbacksOnWorkerThread = 0;
+ if (m_workerContextObserver) {
+ WorkerStorageQuotaContextObserver* observer = m_workerContextObserver;
+ m_workerContextObserver = 0;
+ // The next line may delete this.
+ delete observer;
+ }
+}
+
+WorkerStorageQuotaCallbacksBridge::WorkerStorageQuotaCallbacksBridge(WebCore::WorkerLoaderProxy* workerLoaderProxy, WebCore::ScriptExecutionContext* workerContext, WebStorageQuotaCallbacksImpl* callbacks)
+ : m_workerLoaderProxy(workerLoaderProxy)
+ , m_workerContext(workerContext)
+ , m_workerContextObserver(WorkerStorageQuotaContextObserver::create(static_cast<WorkerContext*>(m_workerContext), this).leakPtr())
+ , m_callbacksOnWorkerThread(callbacks)
+{
+ ASSERT(m_workerContext->isContextThread());
+}
+
+WorkerStorageQuotaCallbacksBridge::~WorkerStorageQuotaCallbacksBridge()
+{
+ // One way or another, the bridge should be stopped before it is destroyed.
+ ASSERT(!m_callbacksOnWorkerThread);
+}
+
+void WorkerStorageQuotaCallbacksBridge::postQueryUsageAndQuotaToMainThread(WebCommonWorkerClient* commonClient, WebStorageQuotaType storageType, const String& mode)
+{
+ dispatchTaskToMainThread(createCallbackTask(&queryUsageAndQuotaOnMainThread, AllowCrossThreadAccess(commonClient), storageType, this, mode));
+}
+
+void WorkerStorageQuotaCallbacksBridge::queryUsageAndQuotaOnMainThread(ScriptExecutionContext*, WebCommonWorkerClient* commonClient, WebStorageQuotaType storageType, PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge, const String& mode)
+{
+ if (!commonClient)
+ bridge->didFailOnMainThread(WebStorageQuotaErrorAbort, mode);
+ else
+ commonClient->queryUsageAndQuota(storageType, MainThreadStorageQuotaCallbacks::createLeakedPtr(bridge, mode));
+}
+
+void WorkerStorageQuotaCallbacksBridge::didFailOnMainThread(WebStorageQuotaError error, const String& mode)
+{
+ mayPostTaskToWorker(createCallbackTask(&didFailOnWorkerThread, this, error), mode);
+}
+
+void WorkerStorageQuotaCallbacksBridge::didQueryStorageUsageAndQuotaOnMainThread(unsigned long long usageInBytes, unsigned long long quotaInBytes, const String& mode)
+{
+ mayPostTaskToWorker(createCallbackTask(&didQueryStorageUsageAndQuotaOnWorkerThread, this, usageInBytes, quotaInBytes), mode);
+}
+
+void WorkerStorageQuotaCallbacksBridge::didFailOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge, WebStorageQuotaError error)
+{
+ bridge->m_callbacksOnWorkerThread->didFail(error);
+}
+
+void WorkerStorageQuotaCallbacksBridge::didQueryStorageUsageAndQuotaOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge, unsigned long long usageInBytes, unsigned long long quotaInBytes)
+{
+ bridge->m_callbacksOnWorkerThread->didQueryStorageUsageAndQuota(usageInBytes, quotaInBytes);
+}
+
+void WorkerStorageQuotaCallbacksBridge::runTaskOnMainThread(WebCore::ScriptExecutionContext* scriptExecutionContext, PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge, PassOwnPtr<WebCore::ScriptExecutionContext::Task> taskToRun)
+{
+ ASSERT(isMainThread());
+ taskToRun->performTask(scriptExecutionContext);
+}
+
+void WorkerStorageQuotaCallbacksBridge::runTaskOnWorkerThread(WebCore::ScriptExecutionContext* scriptExecutionContext, PassRefPtr<WorkerStorageQuotaCallbacksBridge> bridge, PassOwnPtr<WebCore::ScriptExecutionContext::Task> taskToRun)
+{
+ ASSERT(bridge);
+ if (!bridge->m_callbacksOnWorkerThread)
+ return;
+ ASSERT(bridge->m_workerContext);
+ ASSERT(bridge->m_workerContext->isContextThread());
+ ASSERT(taskToRun);
+ taskToRun->performTask(scriptExecutionContext);
+
+ // taskToRun does the callback.
+ bridge->cleanUpAfterCallback();
+
+ // WorkerStorageQuotaCallbacksBridge may be deleted here when bridge goes out of scope.
+}
+
+void WorkerStorageQuotaCallbacksBridge::dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task> task)
+{
+ ASSERT(m_workerLoaderProxy);
+ ASSERT(m_workerContext->isContextThread());
+ WebWorkerBase::dispatchTaskToMainThread(createCallbackTask(&runTaskOnMainThread, RefPtr<WorkerStorageQuotaCallbacksBridge>(this).release(), task));
+}
+
+void WorkerStorageQuotaCallbacksBridge::mayPostTaskToWorker(PassOwnPtr<ScriptExecutionContext::Task> task, const String& mode)
+{
+ // Relies on its caller (MainThreadStorageQuotaCallbacks:did*) to keep WorkerStorageQuotaCallbacksBridge alive.
+ ASSERT(isMainThread());
+
+ MutexLocker locker(m_loaderProxyMutex);
+ if (m_workerLoaderProxy)
+ m_workerLoaderProxy->postTaskForModeToWorkerContext(createCallbackTask(&runTaskOnWorkerThread, this, task), mode);
+}
+
+} // namespace WebCore
Added: trunk/Source/WebKit/chromium/src/WorkerStorageQuotaCallbacksBridge.h (0 => 146633)
--- trunk/Source/WebKit/chromium/src/WorkerStorageQuotaCallbacksBridge.h (rev 0)
+++ trunk/Source/WebKit/chromium/src/WorkerStorageQuotaCallbacksBridge.h 2013-03-22 18:27:02 UTC (rev 146633)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerStorageQuotaCallbacksBridge_h
+#define WorkerStorageQuotaCallbacksBridge_h
+
+#if ENABLE(QUOTA) && ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include "StorageArea.h"
+#include <WebStorageQuotaError.h>
+#include <WebStorageQuotaType.h>
+#include <public/WebVector.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Threading.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+class WorkerLoaderProxy;
+}
+
+namespace WebKit {
+
+class MainThreadStorageQuotaCallbacks;
+class WebCommonWorkerClient;
+class WebStorageQuotaCallbacksImpl;
+class WorkerStorageQuotaContextObserver;
+
+// Used to post a queryUsageAndQuota request to the main thread and get called back for the request.
+//
+// Lifetime for this class is maintained by posted "tasks" which ref count it and by MainThreadStorageQuotaCallbacks.
+// Either a task finishing or the MainThreadStorageQuotaCallbacks being deleted may release the last ref on WorkerStorageQuotaCallbacksBridge.
+//
+// A typical flow for queryUsageAndQuota would look like this:
+// Bridge::postQueryUsageAndQuotaToMainThread() on WorkerThread
+// --> Bridge::queryUsageAndQuotaOnMainThread() is called on MainThread
+// This makes an IPC with a MainThreadStorageQuotaCallbacks instance
+// [actual operation is down in the browser]
+// --> MainThreadStorageQuotaCallbacks::didXxx is called on MainThread
+// --> Bridge::didXxxOnMainThread is called on MainThread
+// --> Bridge::didXxxOnWorkerThread is called on WorkerThread
+// This calls the original callbacks (m_callbacksOnWorkerThread).
+class WorkerStorageQuotaCallbacksBridge : public ThreadSafeRefCounted<WorkerStorageQuotaCallbacksBridge> {
+public:
+ ~WorkerStorageQuotaCallbacksBridge();
+
+ void stop();
+
+ static PassRefPtr<WorkerStorageQuotaCallbacksBridge> create(WebCore::WorkerLoaderProxy* workerLoaderProxy, WebCore::ScriptExecutionContext* workerContext, WebStorageQuotaCallbacksImpl* callbacks)
+ {
+ return adoptRef(new WorkerStorageQuotaCallbacksBridge(workerLoaderProxy, workerContext, callbacks));
+ }
+
+ // Entry method to post QueryUsageAndQuota task to main thread.
+ void postQueryUsageAndQuotaToMainThread(WebCommonWorkerClient*, WebStorageQuotaType, const String& mode);
+
+ // Callback methods that are called on the main thread.
+ void didFailOnMainThread(WebStorageQuotaError, const String& mode);
+ void didQueryStorageUsageAndQuotaOnMainThread(unsigned long long usageInBytes, unsigned long long quotaInBytes, const String& mode);
+
+private:
+ WorkerStorageQuotaCallbacksBridge(WebCore::WorkerLoaderProxy*, WebCore::ScriptExecutionContext*, WebStorageQuotaCallbacksImpl*);
+
+ // Method that is called on the main thread.
+ static void runTaskOnMainThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerStorageQuotaCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
+ static void runTaskOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerStorageQuotaCallbacksBridge>, PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
+ static void queryUsageAndQuotaOnMainThread(WebCore::ScriptExecutionContext*, WebCommonWorkerClient*, WebStorageQuotaType, PassRefPtr<WorkerStorageQuotaCallbacksBridge>, const String& mode);
+
+ friend class MainThreadStorageQuotaCallbacks;
+
+ // Methods that dispatch WebStorageQuotaCallbacks on the worker threads.
+ static void didFailOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerStorageQuotaCallbacksBridge>, WebStorageQuotaError);
+ static void didQueryStorageUsageAndQuotaOnWorkerThread(WebCore::ScriptExecutionContext*, PassRefPtr<WorkerStorageQuotaCallbacksBridge>, unsigned long long usageInBytes, unsigned long long quotaInBytes);
+
+ void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
+ void mayPostTaskToWorker(PassOwnPtr<WebCore::ScriptExecutionContext::Task>, const String& mode);
+
+ void cleanUpAfterCallback();
+
+ Mutex m_loaderProxyMutex;
+ WebCore::WorkerLoaderProxy* m_workerLoaderProxy;
+
+ WebCore::ScriptExecutionContext* m_workerContext;
+
+ // Must be deleted on the WorkerContext thread.
+ WorkerStorageQuotaContextObserver* m_workerContextObserver;
+
+ // This is self-destructed and must be fired on the worker thread.
+ WebStorageQuotaCallbacksImpl* m_callbacksOnWorkerThread;
+};
+
+} // namespace WebCore
+
+#endif
+
+#endif // WorkerStorageQuotaCallbacksBridge_h