1/* 2 * Copyright (C) 2010 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 "WorkerAsyncFileSystemChromium.h" 33 34#if ENABLE(FILE_SYSTEM) 35 36#include "AsyncFileSystemCallbacks.h" 37#include "FileMetadata.h" 38#include "FileSystem.h" 39#include "NotImplemented.h" 40#include "WebFileSystem.h" 41#include "WebFileSystemCallbacksImpl.h" 42#include "WebFileWriter.h" 43#include "WebKit.h" 44#include "WebKitClient.h" 45#include "WebWorkerBase.h" 46#include "WorkerAsyncFileWriterChromium.h" 47#include "WorkerContext.h" 48#include "WorkerFileSystemCallbacksBridge.h" 49#include "WorkerScriptController.h" 50#include "WorkerThread.h" 51#include <wtf/text/CString.h> 52 53using namespace WebKit; 54 55namespace WebCore { 56 57static const char fileSystemOperationsMode[] = "fileSystemOperationsMode"; 58 59WorkerAsyncFileSystemChromium::WorkerAsyncFileSystemChromium(ScriptExecutionContext* context, AsyncFileSystem::Type type, const String& rootPath, bool synchronous) 60 : AsyncFileSystem(type, rootPath) 61 , m_scriptExecutionContext(context) 62 , m_webFileSystem(WebKit::webKitClient()->fileSystem()) 63 , m_workerContext(static_cast<WorkerContext*>(context)) 64 , m_synchronous(synchronous) 65{ 66 ASSERT(m_webFileSystem); 67 ASSERT(m_scriptExecutionContext->isWorkerContext()); 68 69 WorkerLoaderProxy* workerLoaderProxy = &m_workerContext->thread()->workerLoaderProxy(); 70 m_worker = static_cast<WebWorkerBase*>(workerLoaderProxy); 71} 72 73WorkerAsyncFileSystemChromium::~WorkerAsyncFileSystemChromium() 74{ 75} 76 77bool WorkerAsyncFileSystemChromium::waitForOperationToComplete() 78{ 79 if (!m_bridgeForCurrentOperation.get()) 80 return false; 81 82 RefPtr<WorkerFileSystemCallbacksBridge> bridge = m_bridgeForCurrentOperation.release(); 83 if (m_workerContext->thread()->runLoop().runInMode(m_workerContext, m_modeForCurrentOperation) == MessageQueueTerminated) { 84 bridge->stop(); 85 return false; 86 } 87 return true; 88} 89 90void WorkerAsyncFileSystemChromium::move(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 91{ 92 createWorkerFileSystemCallbacksBridge(callbacks)->postMoveToMainThread(m_webFileSystem, sourcePath, destinationPath, m_modeForCurrentOperation); 93} 94 95void WorkerAsyncFileSystemChromium::copy(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 96{ 97 createWorkerFileSystemCallbacksBridge(callbacks)->postCopyToMainThread(m_webFileSystem, sourcePath, destinationPath, m_modeForCurrentOperation); 98} 99 100void WorkerAsyncFileSystemChromium::remove(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 101{ 102 createWorkerFileSystemCallbacksBridge(callbacks)->postRemoveToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); 103} 104 105void WorkerAsyncFileSystemChromium::removeRecursively(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 106{ 107 createWorkerFileSystemCallbacksBridge(callbacks)->postRemoveRecursivelyToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); 108} 109 110void WorkerAsyncFileSystemChromium::readMetadata(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 111{ 112 createWorkerFileSystemCallbacksBridge(callbacks)->postReadMetadataToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); 113} 114 115void WorkerAsyncFileSystemChromium::createFile(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 116{ 117 createWorkerFileSystemCallbacksBridge(callbacks)->postCreateFileToMainThread(m_webFileSystem, path, exclusive, m_modeForCurrentOperation); 118} 119 120void WorkerAsyncFileSystemChromium::createDirectory(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 121{ 122 createWorkerFileSystemCallbacksBridge(callbacks)->postCreateDirectoryToMainThread(m_webFileSystem, path, exclusive, m_modeForCurrentOperation); 123} 124 125void WorkerAsyncFileSystemChromium::fileExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 126{ 127 createWorkerFileSystemCallbacksBridge(callbacks)->postFileExistsToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); 128} 129 130void WorkerAsyncFileSystemChromium::directoryExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 131{ 132 createWorkerFileSystemCallbacksBridge(callbacks)->postDirectoryExistsToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); 133} 134 135void WorkerAsyncFileSystemChromium::readDirectory(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 136{ 137 createWorkerFileSystemCallbacksBridge(callbacks)->postReadDirectoryToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); 138} 139 140class WorkerFileWriterHelperCallbacks : public AsyncFileSystemCallbacks { 141public: 142 static PassOwnPtr<WorkerFileWriterHelperCallbacks> create(AsyncFileWriterClient* client, const String& path, WebKit::WebFileSystem* webFileSystem, PassOwnPtr<WebCore::AsyncFileSystemCallbacks> callbacks, WorkerContext* workerContext) 143 { 144 return adoptPtr(new WorkerFileWriterHelperCallbacks(client, path, webFileSystem, callbacks, workerContext)); 145 } 146 147 virtual void didSucceed() 148 { 149 ASSERT_NOT_REACHED(); 150 } 151 152 virtual void didReadMetadata(const FileMetadata& metadata) 153 { 154 ASSERT(m_callbacks); 155 if (metadata.type != FileMetadata::TypeFile || metadata.length < 0) 156 m_callbacks->didFail(WebKit::WebFileErrorInvalidState); 157 else { 158 OwnPtr<WorkerAsyncFileWriterChromium> asyncFileWriterChromium = WorkerAsyncFileWriterChromium::create(m_webFileSystem, m_path, m_workerContext, m_client, WorkerAsyncFileWriterChromium::Asynchronous); 159 m_callbacks->didCreateFileWriter(asyncFileWriterChromium.release(), metadata.length); 160 } 161 } 162 163 virtual void didReadDirectoryEntry(const String& name, bool isDirectory) 164 { 165 ASSERT_NOT_REACHED(); 166 } 167 168 virtual void didReadDirectoryEntries(bool hasMore) 169 { 170 ASSERT_NOT_REACHED(); 171 } 172 173 virtual void didOpenFileSystem(const String&, PassOwnPtr<AsyncFileSystem>) 174 { 175 ASSERT_NOT_REACHED(); 176 } 177 178 // Called when an AsyncFileWrter has been created successfully. 179 virtual void didCreateFileWriter(PassOwnPtr<AsyncFileWriter>, long long) 180 { 181 ASSERT_NOT_REACHED(); 182 } 183 184 virtual void didFail(int code) 185 { 186 ASSERT(m_callbacks); 187 m_callbacks->didFail(code); 188 } 189 190private: 191 WorkerFileWriterHelperCallbacks(AsyncFileWriterClient* client, const String& path, WebKit::WebFileSystem* webFileSystem, PassOwnPtr<WebCore::AsyncFileSystemCallbacks> callbacks, WorkerContext* workerContext) 192 : m_client(client) 193 , m_path(path) 194 , m_webFileSystem(webFileSystem) 195 , m_callbacks(callbacks) 196 , m_workerContext(workerContext) 197 { 198 } 199 200 AsyncFileWriterClient* m_client; 201 String m_path; 202 WebKit::WebFileSystem* m_webFileSystem; 203 OwnPtr<WebCore::AsyncFileSystemCallbacks> m_callbacks; 204 WorkerContext* m_workerContext; 205}; 206 207void WorkerAsyncFileSystemChromium::createWriter(AsyncFileWriterClient* client, const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 208{ 209 createWorkerFileSystemCallbacksBridge(WorkerFileWriterHelperCallbacks::create(client, path, m_webFileSystem, callbacks, m_workerContext))->postReadMetadataToMainThread(m_webFileSystem, path, m_modeForCurrentOperation); 210} 211 212PassRefPtr<WorkerFileSystemCallbacksBridge> WorkerAsyncFileSystemChromium::createWorkerFileSystemCallbacksBridge(PassOwnPtr<AsyncFileSystemCallbacks> callbacks) 213{ 214 ASSERT(!m_synchronous || !m_bridgeForCurrentOperation.get()); 215 216 m_modeForCurrentOperation = fileSystemOperationsMode; 217 m_modeForCurrentOperation.append(String::number(m_workerContext->thread()->runLoop().createUniqueId())); 218 219 m_bridgeForCurrentOperation = WorkerFileSystemCallbacksBridge::create(m_worker, m_scriptExecutionContext, new WebKit::WebFileSystemCallbacksImpl(callbacks)); 220 return m_bridgeForCurrentOperation; 221} 222 223} // namespace WebCore 224 225#endif // ENABLE(FILE_SYSTEM) 226