Home | History | Annotate | Download | only in src
      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 
     53 using namespace WebKit;
     54 
     55 namespace WebCore {
     56 
     57 static const char fileSystemOperationsMode[] = "fileSystemOperationsMode";
     58 
     59 WorkerAsyncFileSystemChromium::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 
     73 WorkerAsyncFileSystemChromium::~WorkerAsyncFileSystemChromium()
     74 {
     75 }
     76 
     77 bool 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 
     90 void WorkerAsyncFileSystemChromium::move(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
     91 {
     92     createWorkerFileSystemCallbacksBridge(callbacks)->postMoveToMainThread(m_webFileSystem, sourcePath, destinationPath, m_modeForCurrentOperation);
     93 }
     94 
     95 void WorkerAsyncFileSystemChromium::copy(const String& sourcePath, const String& destinationPath, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
     96 {
     97     createWorkerFileSystemCallbacksBridge(callbacks)->postCopyToMainThread(m_webFileSystem, sourcePath, destinationPath, m_modeForCurrentOperation);
     98 }
     99 
    100 void WorkerAsyncFileSystemChromium::remove(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    101 {
    102     createWorkerFileSystemCallbacksBridge(callbacks)->postRemoveToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
    103 }
    104 
    105 void WorkerAsyncFileSystemChromium::removeRecursively(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    106 {
    107     createWorkerFileSystemCallbacksBridge(callbacks)->postRemoveRecursivelyToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
    108 }
    109 
    110 void WorkerAsyncFileSystemChromium::readMetadata(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    111 {
    112     createWorkerFileSystemCallbacksBridge(callbacks)->postReadMetadataToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
    113 }
    114 
    115 void WorkerAsyncFileSystemChromium::createFile(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    116 {
    117     createWorkerFileSystemCallbacksBridge(callbacks)->postCreateFileToMainThread(m_webFileSystem, path, exclusive, m_modeForCurrentOperation);
    118 }
    119 
    120 void WorkerAsyncFileSystemChromium::createDirectory(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    121 {
    122     createWorkerFileSystemCallbacksBridge(callbacks)->postCreateDirectoryToMainThread(m_webFileSystem, path, exclusive, m_modeForCurrentOperation);
    123 }
    124 
    125 void WorkerAsyncFileSystemChromium::fileExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    126 {
    127     createWorkerFileSystemCallbacksBridge(callbacks)->postFileExistsToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
    128 }
    129 
    130 void WorkerAsyncFileSystemChromium::directoryExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    131 {
    132     createWorkerFileSystemCallbacksBridge(callbacks)->postDirectoryExistsToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
    133 }
    134 
    135 void WorkerAsyncFileSystemChromium::readDirectory(const String& path, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
    136 {
    137     createWorkerFileSystemCallbacksBridge(callbacks)->postReadDirectoryToMainThread(m_webFileSystem, path, m_modeForCurrentOperation);
    138 }
    139 
    140 class WorkerFileWriterHelperCallbacks : public AsyncFileSystemCallbacks {
    141 public:
    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 
    190 private:
    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 
    207 void 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 
    212 PassRefPtr<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