WebCore/ChangeLog

 12010-09-15 Kinuko Yasuda <kinuko@google.com>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Add Worker support for FileSystem API
 6 https://bugs.webkit.org/show_bug.cgi?id=45808
 7
 8 Exposed requestFileSystem and Flags constructor on worker contexts.
 9
 10 Also changed how to get the base path for Web file systems (in non-chromium ports) so that it works for workers too. This patch assumes each port calls LocalFileSystem::initializeLocalFileSystem() in its initialization phase.
 11
 12 No new tests; tests will be added when we have complete implementation.
 13
 14 * fileapi/LocalFileSystem.cpp:
 15 (WebCore::LocalFileSystem::initializeLocalFileSystem):
 16 (WebCore::LocalFileSystem::localFileSystem):
 17 (WebCore::LocalFileSystem::fileSystemBasePath):
 18 (WebCore::LocalFileSystem::requestFileSystem):
 19 * fileapi/LocalFileSystem.h:
 20 (WebCore::LocalFileSystem::~LocalFileSystem):
 21 * page/DOMWindow.cpp:
 22 (WebCore::DOMWindow::requestFileSystem):
 23 * page/DOMWindow.h:
 24 * page/DOMWindow.idl:
 25 * page/Settings.cpp:
 26 * page/Settings.h:
 27 * workers/WorkerContext.cpp:
 28 (WebCore::WorkerContext::requestFileSystem): Added.
 29 * workers/WorkerContext.h:
 30 * workers/WorkerContext.idl:
 31
1322010-09-14 Kinuko Yasuda <kinuko@chromium.org>
233
334 Reviewed by Dumitru Daniliuc.

WebCore/fileapi/LocalFileSystem.cpp

5050
5151namespace WebCore {
5252
53 PassRefPtr<LocalFileSystem> LocalFileSystem::create(const String& basePath)
 53static LocalFileSystem* staticLocalFileSystem = 0;
 54
 55void LocalFileSystem::initializeLocalFileSystem(const String& basePath)
 56{
 57 // FIXME: Should initialize the quota settings as well.
 58 ASSERT(!staticLocalFileSystem);
 59 if (staticLocalFileSystem)
 60 return;
 61
 62 staticLocalFileSystem = new LocalFileSystem(basePath);
 63}
 64
 65LocalFileSystem& LocalFileSystem::localFileSystem()
 66{
 67 if (!staticLocalFileSystem)
 68 staticLocalFileSystem = new LocalFileSystem("");
 69
 70 return *staticLocalFileSystem;
 71}
 72
 73String LocalFileSystem::fileSystemBasePath() const
5474{
55  return adoptRef(new LocalFileSystem(basePath));
 75 return m_basePath.threadsafeCopy();
5676}
5777
5878static void openFileSystem(ScriptExecutionContext*, const String& basePath, const String& identifier, AsyncFileSystem::Type type, PassOwnPtr<FileSystemCallbacks> callbacks)

@@void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFi
6888 }
6989
7090 // AsyncFileSystem::openFileSystem calls callbacks synchronously, so the method needs to be called asynchronously.
71  context->postTask(createCallbackTask(&openFileSystem, m_basePath, context->securityOrigin()->databaseIdentifier(), type, new FileSystemCallbacks(successCallback, errorCallback, context)));
 91 context->postTask(createCallbackTask(&openFileSystem, fileSystemBasePath(), context->securityOrigin()->databaseIdentifier(), type, new FileSystemCallbacks(successCallback, errorCallback, context)));
7292}
7393
7494} // namespace

WebCore/fileapi/LocalFileSystem.h

@@class ErrorCallback;
4444class FileSystemCallback;
4545class ScriptExecutionContext;
4646
47 class LocalFileSystem : public RefCounted<LocalFileSystem> {
 47// Keeps per-process information and provides an entry point to open a file system.
 48class LocalFileSystem : public Noncopyable {
4849public:
49  static PassRefPtr<LocalFileSystem> create(const String& basePath);
50  virtual ~LocalFileSystem() { }
 50 // Returns a per-process instance of LocalFileSystem.
 51 // Note that LocalFileSystem::initializeLocalFileSystem must be called to
 52 // initialize the base path.
 53 static LocalFileSystem& localFileSystem();
5154
5255 void requestFileSystem(ScriptExecutionContext*, AsyncFileSystem::Type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
5356
54 protected:
 57#if !PLATFORM(CHROMIUM)
 58 // This must be called before any worker threads are created.
 59 void initializeLocalFileSystem(const String&);
 60
 61 String fileSystemBasePath() const;
 62#endif
 63
 64private:
5565 LocalFileSystem(const String& basePath)
5666 : m_basePath(basePath)
5767 {
5868 }
5969
 70 ~LocalFileSystem() { }
 71
 72 // The member methods shouldn't access this String directly but should use
 73 // fileSystemBasePath() instead.
6074 String m_basePath;
6175};
6276

WebCore/page/DOMWindow.cpp

8989
9090#if ENABLE(FILE_SYSTEM)
9191#include "AsyncFileSystem.h"
92 #include "DOMFileSystem.h"
9392#include "ErrorCallback.h"
9493#include "FileError.h"
9594#include "FileSystemCallback.h"

@@void DOMWindow::requestFileSystem(int type, long long size, PassRefPtr<FileSyste
727726 if (!document)
728727 return;
729728
730  if (!m_localFileSystem) {
731  // FIXME: See if access is allowed.
732 
733  Page* page = document->page();
734  if (!page) {
735  DOMFileSystem::scheduleCallback(document, errorCallback, FileError::create(INVALID_STATE_ERR));
736  return;
737  }
738 
739  // FIXME: Get the quota settings as well.
740  String path = page->settings()->fileSystemRootPath();
741  m_localFileSystem = LocalFileSystem::create(path);
742  }
 729 // FIXME: See if access is allowed.
743730
744  m_localFileSystem->requestFileSystem(document, static_cast<AsyncFileSystem::Type>(type), size, successCallback, errorCallback);
 731 LocalFileSystem::localFileSystem().requestFileSystem(document, static_cast<AsyncFileSystem::Type>(type), size, successCallback, errorCallback);
745732}
746733
747734COMPILE_ASSERT(int(DOMWindow::TEMPORARY) == int(AsyncFileSystem::Temporary), enum_mismatch);

WebCore/page/DOMWindow.h

@@namespace WebCore {
5858 class History;
5959 class IDBFactory;
6060 class InspectorTimelineAgent;
61  class LocalFileSystem;
6261 class Location;
6362 class StyleMedia;
6463 class Navigator;

@@namespace WebCore {
444443#if ENABLE(INDEXED_DATABASE)
445444 mutable RefPtr<IDBFactory> m_idbFactory;
446445#endif
447 #if ENABLE(FILE_SYSTEM)
448  RefPtr<LocalFileSystem> m_localFileSystem;
449 #endif
450446
451447 EventTargetData m_eventTargetData;
452448

WebCore/page/DOMWindow.idl

@@module window {
193193 const unsigned short TEMPORARY = 0;
194194 const unsigned short PERSISTENT = 1;
195195 [EnabledAtRuntime] void requestFileSystem(in unsigned short type, in long long size, in [Callback, Optional] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
196 
197196 attribute [EnabledAtRuntime=FileSystem] FlagsConstructor Flags;
198197#endif
199198

WebCore/page/Settings.cpp

@@void Settings::setLocalStorageDatabasePath(const String& path)
490490 m_localStorageDatabasePath = path;
491491}
492492
493 void Settings::setFileSystemRootPath(const String& path)
494 {
495  m_fileSystemRootPath = path;
496 }
497 
498493void Settings::setApplicationChromeMode(bool mode)
499494{
500495 m_inApplicationChromeMode = mode;

WebCore/page/Settings.h

@@namespace WebCore {
239239 void setLocalStorageDatabasePath(const String&);
240240 const String& localStorageDatabasePath() const { return m_localStorageDatabasePath; }
241241
242  void setFileSystemRootPath(const String&);
243  const String& fileSystemRootPath() const { return m_fileSystemRootPath; }
244 
245242 void setApplicationChromeMode(bool);
246243 bool inApplicationChromeMode() const { return m_inApplicationChromeMode; }
247244

@@namespace WebCore {
331328 String m_defaultTextEncodingName;
332329 String m_ftpDirectoryTemplatePath;
333330 String m_localStorageDatabasePath;
334  String m_fileSystemRootPath;
335331 KURL m_userStyleSheetLocation;
336332 AtomicString m_standardFontFamily;
337333 AtomicString m_fixedFontFamily;

WebCore/workers/WorkerContext.cpp

6363#include "NotificationCenter.h"
6464#endif
6565
 66#if ENABLE(FILE_SYSTEM)
 67#include "AsyncFileSystem.h"
 68#include "ErrorCallback.h"
 69#include "FileError.h"
 70#include "FileSystemCallback.h"
 71#include "LocalFileSystem.h"
 72#endif
 73
6674namespace WebCore {
6775
6876class CloseWorkerContextTask : public ScriptExecutionContext::Task {

@@void WorkerContext::revokeBlobURL(const String& blobURLString)
335343}
336344#endif
337345
 346#if ENABLE(FILE_SYSTEM)
 347void WorkerContext::requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)
 348{
 349 // FIXME: see if access is allowed.
 350
 351 LocalFileSystem::localFileSystem().requestFileSystem(this, static_cast<AsyncFileSystem::Type>(type), size, successCallback, errorCallback);
 352}
 353
 354COMPILE_ASSERT(int(WorkerContext::TEMPORARY) == int(AsyncFileSystem::Temporary), enum_mismatch);
 355COMPILE_ASSERT(int(WorkerContext::PERSISTENT) == int(AsyncFileSystem::Persistent), enum_mismatch);
 356#endif
 357
338358} // namespace WebCore
339359
340360#endif // ENABLE(WORKERS)

WebCore/workers/WorkerContext.h

@@namespace WebCore {
4747 class Database;
4848 class DatabaseCallback;
4949 class DatabaseSync;
 50 class ErrorCallback;
 51 class FileSystemCallback;
5052 class NotificationCenter;
5153 class ScheduledAction;
5254 class WorkerLocation;

@@namespace WebCore {
121123 void revokeBlobURL(const String&);
122124#endif
123125
 126#if ENABLE(FILE_SYSTEM)
 127 // They are placed here and in all capital letters to enforce compile-time enum checking.
 128 enum FileSystemType {
 129 TEMPORARY,
 130 PERSISTENT,
 131 };
 132 void requestFileSystem(int type, long long size, PassRefPtr<FileSystemCallback>, PassRefPtr<ErrorCallback>);
 133#endif
 134
124135 // These methods are used for GC marking. See JSWorkerContext::markChildren(MarkStack&) in
125136 // JSWorkerContextCustom.cpp.
126137 WorkerNavigator* optionalNavigator() const { return m_navigator.get(); }

WebCore/workers/WorkerContext.idl

@@module threads {
104104 DOMString createBlobURL(in Blob blob);
105105 void revokeBlobURL(in DOMString blobURL);
106106#endif
 107
 108#if defined(ENABLE_FILE_SYSTEM) && ENABLE_FILE_SYSTEM
 109 const unsigned short TEMPORARY = 0;
 110 const unsigned short PERSISTENT = 1;
 111 [EnabledAtRuntime] void requestFileSystem(in unsigned short type, in long long size, in [Callback, Optional] FileSystemCallback successCallback, in [Callback, Optional] ErrorCallback errorCallback);
 112 attribute [EnabledAtRuntime=FileSystem] FlagsConstructor Flags;
 113#endif
107114 };
108115
109116}

WebKit/chromium/ChangeLog

 12010-09-15 Kinuko Yasuda <kinuko@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 Add Worker support for FileSystem API
 6 https://bugs.webkit.org/show_bug.cgi?id=45808
 7
 8 * public/WebCommonWorkerClient.h:
 9 (WebKit::WebCommonWorkerClient::openFileSystem): Added.
 10 * src/LocalFileSystemChromium.cpp:
 11 (WebCore::LocalFileSystem::localFileSystem):
 12 (WebCore::LocalFileSystem::requestFileSystem):
 13 * src/WebWorkerBase.cpp:
 14 (WebKit::WebWorkerBase::openFileSystem): Added.
 15 * src/WebWorkerBase.h:
 16 * src/WebWorkerClientImpl.h:
 17 (WebKit::WebWorkerClientImpl::openFileSystem): Added.
 18
1192010-09-14 Sheriff Bot <webkit.review.bot@gmail.com>
220
321 Unreviewed, rolling out r67503.

WebKit/chromium/public/WebCommonWorkerClient.h

3131#ifndef WebCommonWorkerClient_h
3232#define WebCommonWorkerClient_h
3333
 34#include "WebCommon.h"
 35#include "WebFileSystem.h"
 36
3437namespace WebKit {
3538
3639class WebApplicationCacheHost;

@@public:
8386 // Called on the main webkit thread before opening a web database.
8487 virtual bool allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize) = 0;
8588
 89 // Called on the main webkit thread before opening a file system.
 90 virtual void openFileSystem(WebFrame*, WebFileSystem::Type, long long size, WebFileSystemCallbacks*)
 91 {
 92 // FIXME: We need a stub implementation until subclass in chromium implement this.
 93 WEBKIT_ASSERT_NOT_REACHED();
 94 }
 95
8696protected:
8797 ~WebCommonWorkerClient() { }
8898};

WebKit/chromium/src/LocalFileSystemChromium.cpp

4242#include "WebFileSystemCallbacksImpl.h"
4343#include "WebFrameClient.h"
4444#include "WebFrameImpl.h"
 45#include "WebWorkerImpl.h"
 46#include "WorkerContext.h"
 47#include "WorkerThread.h"
4548
4649using namespace WebKit;
4750
4851namespace WebCore {
4952
50 PassRefPtr<LocalFileSystem> LocalFileSystem::create(const String& path)
 53LocalFileSystem& LocalFileSystem::localFileSystem()
5154{
52  return adoptRef(new LocalFileSystem(path));
 55 DEFINE_STATIC_LOCAL(LocalFileSystem, localFileSystem, (""));
 56 return localFileSystem;
5357}
5458
5559void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFileSystem::Type type, long long size, PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback)

@@void LocalFileSystem::requestFileSystem(ScriptExecutionContext* context, AsyncFi
6064 WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame());
6165 webFrame->client()->openFileSystem(webFrame, static_cast<WebFileSystem::Type>(type), size, new WebFileSystemCallbacksImpl(new FileSystemCallbacks(successCallback, errorCallback, context)));
6266 } else {
63  // FIXME: Add implementation for workers.
 67 WorkerContext* workerContext = static_cast<WorkerContext*>(context);
 68 WorkerLoaderProxy* workerLoaderProxy = &workerContext->thread()->workerLoaderProxy();
 69 WebWorkerBase* webWorker = static_cast<WebWorkerBase*>(workerLoaderProxy);
 70 webWorker->openFileSystem(0, static_cast<WebFileSystem::Type>(type), size, new WebFileSystemCallbacksImpl(new FileSystemCallbacks(successCallback, errorCallback, context)));
6471 }
6572}
6673

WebKit/chromium/src/WebWorkerBase.cpp

3737#include "PlatformMessagePortChannel.h"
3838
3939#include "WebDataSourceImpl.h"
 40#include "WebFileError.h"
 41#include "WebFileSystemCallbacks.h"
4042#include "WebFrameClient.h"
4143#include "WebFrameImpl.h"
4244#include "WebMessagePortChannel.h"

@@namespace WebKit {
5658#if ENABLE(WORKERS)
5759
5860static const char allowDatabaseMode[] = "allowDatabaseMode";
 61static const char openFileSystemMode[] = "openFileSystemMode";
 62
5963
6064namespace {
6165

@@private:
114118 WebWorkerBase* m_worker;
115119 WTF::String m_mode;
116120};
 121
 122// This class is used to post a openFileSystem request to the main thread.
 123// This must be destructed on the worker thread.
 124class OpenFileSystemMainThreadBridge {
 125public:
 126 static void start(WebWorkerBase* worker, WebCommonWorkerClient* commonClient, WebFrame* frame, const WTF::String& mode, WebFileSystem::Type type, long long size, WebFileSystemCallbacks* callbacks)
 127 {
 128 // This class is self-destructed.
 129 ASSERT(new OpenFileSystemMainThreadBridge(worker, commonClient, frame, mode, type, size, callbacks));
 130 }
 131
 132 ~OpenFileSystemMainThreadBridge()
 133 {
 134 ASSERT(!m_workerContextCallbacks);
 135 }
 136
 137private:
 138 OpenFileSystemMainThreadBridge(WebWorkerBase* worker, WebCommonWorkerClient* commonClient, WebFrame* frame, const WTF::String& mode, WebFileSystem::Type type, long long size, WebFileSystemCallbacks* callbacks)
 139 : m_worker(worker)
 140 , m_workerContextCallbacks(callbacks)
 141 , m_mode(mode)
 142 {
 143 worker->dispatchTaskToMainThread(createCallbackTask(&openFileSystemOnMainThread, worker, commonClient, frame, type, size, this));
 144 }
 145
 146 static void openFileSystemOnMainThread(WebCore::ScriptExecutionContext*, WebWorkerBase* worker, WebCommonWorkerClient* commonClient, WebFrame* frame, WebFileSystem::Type type, long long size, OpenFileSystemMainThreadBridge* bridge)
 147 {
 148 if (!commonClient)
 149 bridge->didFailOnMainThread(WebFileErrorAbort);
 150 else
 151 commonClient->openFileSystem(frame, type, size, new MainThreadFileSystemCallbacks(bridge));
 152 }
 153
 154 // FileSystemCallbacks that are dispatched on the main thread.
 155 class MainThreadFileSystemCallbacks : public WebFileSystemCallbacks {
 156 public:
 157 MainThreadFileSystemCallbacks(PassOwnPtr<OpenFileSystemMainThreadBridge> bridge)
 158 : m_bridge(bridge)
 159 {
 160 }
 161
 162 virtual ~MainThreadFileSystemCallbacks()
 163 {
 164 if (m_bridge)
 165 didFail(WebFileErrorAbort);
 166 }
 167
 168 virtual void didOpenFileSystem(const WebString& name, const WebString& path)
 169 {
 170 ASSERT(m_bridge);
 171 m_bridge.leakPtr()->didOpenFileSystemOnMainThread(name, path);
 172 delete this;
 173 }
 174
 175 virtual void didFail(WebFileError error)
 176 {
 177 ASSERT(m_bridge);
 178 m_bridge.leakPtr()->didFailOnMainThread(error);
 179 delete this;
 180 }
 181
 182 virtual void didSucceed() { WEBKIT_ASSERT_NOT_REACHED(); }
 183 virtual void didReadMetadata(const WebFileInfo&) { WEBKIT_ASSERT_NOT_REACHED(); }
 184 virtual void didReadDirectory(const WebVector<WebFileSystemEntry>&, bool) { WEBKIT_ASSERT_NOT_REACHED(); }
 185
 186 private:
 187 OwnPtr<OpenFileSystemMainThreadBridge> m_bridge;
 188 };
 189 friend class MainThreadFileSystemCallbacks;
 190
 191 static void didFailOnWorkerThread(WebCore::ScriptExecutionContext*, OpenFileSystemMainThreadBridge* bridgePtr, WebFileError error)
 192 {
 193 OwnPtr<OpenFileSystemMainThreadBridge> bridge(bridgePtr);
 194 bridge->m_workerContextCallbacks->didFail(error);
 195 bridge->m_workerContextCallbacks = 0;
 196 }
 197
 198 static void didOpenFileSystemOnWorkerThread(WebCore::ScriptExecutionContext*, OpenFileSystemMainThreadBridge* bridgePtr, const WTF::String& name, const WTF::String& rootPath)
 199 {
 200 OwnPtr<OpenFileSystemMainThreadBridge> bridge(bridgePtr);
 201 bridge->m_workerContextCallbacks->didOpenFileSystem(name, rootPath);
 202 bridge->m_workerContextCallbacks = 0;
 203 }
 204
 205 void didFailOnMainThread(WebFileError error)
 206 {
 207 m_worker->postTaskForModeToWorkerContext(createCallbackTask(&didFailOnWorkerThread, this, error), m_mode);
 208 }
 209
 210 void didOpenFileSystemOnMainThread(const WTF::String& name, const WTF::String& rootPath)
 211 {
 212 m_worker->postTaskForModeToWorkerContext(createCallbackTask(&didOpenFileSystemOnWorkerThread, this, name, rootPath), m_mode);
 213 }
 214
 215 WebWorkerBase* m_worker;
 216 WebFileSystemCallbacks* m_workerContextCallbacks;
 217 WTF::String m_mode;
 218};
 219
117220}
118221
119222// This function is called on the main thread to force to initialize some static

@@bool WebWorkerBase::allowDatabase(WebFrame*, const WebString& name, const WebStr
231334 return bridge->result();
232335}
233336
 337void WebWorkerBase::openFileSystem(WebFrame*, WebFileSystem::Type type, long long size, WebFileSystemCallbacks* callbacks)
 338{
 339 ASSERT(m_webView);
 340
 341 // The mainFrame is used to check the security origin.
 342 OpenFileSystemMainThreadBridge::start(this, commonClient(), m_webView->mainFrame(), openFileSystemMode, type, size, callbacks);
 343}
 344
234345// WorkerObjectProxy -----------------------------------------------------------
235346
236347void WebWorkerBase::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message,

WebKit/chromium/src/WebWorkerBase.h

@@public:
9191 // Controls whether access to Web Databases is allowed for this worker.
9292 virtual bool allowDatabase(WebFrame*, const WebString& name, const WebString& displayName, unsigned long estimatedSize);
9393
 94 // Requests to open a file system for this worker.
 95 virtual void openFileSystem(WebFrame*, WebFileSystem::Type, long long size, WebFileSystemCallbacks*);
 96
9497 // Executes the given task on the main thread.
9598 static void dispatchTaskToMainThread(PassOwnPtr<WebCore::ScriptExecutionContext::Task>);
9699

WebKit/chromium/src/WebWorkerClientImpl.h

3333
3434#if ENABLE(WORKERS)
3535
 36#include "WebFileSystem.h"
3637#include "WebWorkerClient.h"
37 
3838#include "WorkerContextProxy.h"
3939#include <wtf/PassOwnPtr.h>
4040#include <wtf/RefPtr.h>

@@public:
9999 ASSERT_NOT_REACHED();
100100 return true;
101101 }
 102 virtual void openFileSystem(WebFrame*, WebFileSystem::Type, long long size, WebFileSystemCallbacks*)
 103 {
 104 ASSERT_NOT_REACHED();
 105 }
102106
103107private:
104108 virtual ~WebWorkerClientImpl();