diff options
author | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 00:44:08 +0000 |
---|---|---|
committer | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-14 00:44:08 +0000 |
commit | 2687ad7d62c737430aa780f9db9a0a166931a735 (patch) | |
tree | 5e5a5eb1a62948713721241ebf87bbd0690ac341 | |
parent | 1dfff5c058db41e3b2caa74159ee7ed458bc9d69 (diff) | |
download | chromium_src-2687ad7d62c737430aa780f9db9a0a166931a735.zip chromium_src-2687ad7d62c737430aa780f9db9a0a166931a735.tar.gz chromium_src-2687ad7d62c737430aa780f9db9a0a166931a735.tar.bz2 |
SimpleFileWriter for test_shell and DRT.
BUG=none
TEST=manual
Review URL: http://codereview.chromium.org/3683004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62486 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/common/file_system/webfilewriter_impl.cc | 181 | ||||
-rw-r--r-- | chrome/common/file_system/webfilewriter_impl.h | 50 | ||||
-rw-r--r-- | webkit/fileapi/file_system_callback_dispatcher.h | 2 | ||||
-rw-r--r-- | webkit/fileapi/webfilewriter_base.cc | 145 | ||||
-rw-r--r-- | webkit/fileapi/webfilewriter_base.h | 69 | ||||
-rw-r--r-- | webkit/fileapi/webkit_fileapi.gypi | 2 | ||||
-rw-r--r-- | webkit/support/webkit_support.gypi | 2 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_file_system.cc | 13 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_file_system.h | 2 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_file_writer.cc | 186 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_file_writer.h | 45 | ||||
-rw-r--r-- | webkit/tools/test_shell/simple_resource_loader_bridge.cc | 3 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_webview_delegate.cc | 1 |
13 files changed, 516 insertions, 185 deletions
diff --git a/chrome/common/file_system/webfilewriter_impl.cc b/chrome/common/file_system/webfilewriter_impl.cc index 6314c91..2f3677b 100644 --- a/chrome/common/file_system/webfilewriter_impl.cc +++ b/chrome/common/file_system/webfilewriter_impl.cc @@ -5,19 +5,23 @@ #include "chrome/common/file_system/webfilewriter_impl.h" #include "chrome/common/child_thread.h" -#include "chrome/common/file_system/webfilesystem_impl.h" -#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h" -#include "third_party/WebKit/WebKit/chromium/public/WebFileWriterClient.h" -#include "third_party/WebKit/WebKit/chromium/public/WebURL.h" -#include "webkit/glue/webkit_glue.h" +#include "chrome/common/file_system/file_system_dispatcher.h" -class WebFileWriterImpl::FileSystemCallbackDispatcherImpl : - public fileapi::FileSystemCallbackDispatcher { +namespace { + +inline FileSystemDispatcher* GetFileSystemDispatcher() { + return ChildThread::current()->file_system_dispatcher(); +} + +} + +class WebFileWriterImpl::CallbackDispatcher + : public fileapi::FileSystemCallbackDispatcher { public: - explicit FileSystemCallbackDispatcherImpl( - const base::WeakPtr<WebFileWriterImpl>& impl) : m_impl(impl) { + explicit CallbackDispatcher( + const base::WeakPtr<WebFileWriterImpl>& writer) : writer_(writer) { } - virtual ~FileSystemCallbackDispatcherImpl() { + virtual ~CallbackDispatcher() { } virtual void DidReadMetadata(const base::PlatformFileInfo&) { @@ -33,162 +37,45 @@ class WebFileWriterImpl::FileSystemCallbackDispatcherImpl : NOTREACHED(); } virtual void DidSucceed() { - if (m_impl) - m_impl->DidSucceed(); + if (writer_) + writer_->DidSucceed(); } virtual void DidFail(base::PlatformFileError error_code) { - if (m_impl) - m_impl->DidFail(error_code); + if (writer_) + writer_->DidFail(error_code); } virtual void DidWrite(int64 bytes, bool complete) { - if (m_impl) - m_impl->DidWrite(bytes, complete); + if (writer_) + writer_->DidWrite(bytes, complete); } private: - base::WeakPtr<WebFileWriterImpl> m_impl; + base::WeakPtr<WebFileWriterImpl> writer_; }; WebFileWriterImpl::WebFileWriterImpl( const WebKit::WebString& path, WebKit::WebFileWriterClient* client) - : path_(webkit_glue::WebStringToFilePath(path)), - client_(client), - request_id_(0), - operation_(kOperationNone), - cancel_state_(kCancelNotInProgress) { + : WebFileWriterBase(path, client), + request_id_(0) { } WebFileWriterImpl::~WebFileWriterImpl() { } -void WebFileWriterImpl::truncate( - long long length) { - DCHECK(kOperationNone == operation_); - DCHECK(kCancelNotInProgress == cancel_state_); - operation_ = kOperationTruncate; - FileSystemDispatcher* dispatcher = - ChildThread::current()->file_system_dispatcher(); - dispatcher->Truncate( - path_, length, &request_id_, - new FileSystemCallbackDispatcherImpl(AsWeakPtr())); -} - -void WebFileWriterImpl::write( - long long position, - const WebKit::WebURL& blob_url) { - DCHECK(kOperationNone == operation_); - DCHECK(kCancelNotInProgress == cancel_state_); - operation_ = kOperationWrite; - FileSystemDispatcher* dispatcher = - ChildThread::current()->file_system_dispatcher(); - dispatcher->Write( - path_, blob_url, position, &request_id_, - new FileSystemCallbackDispatcherImpl(AsWeakPtr())); -} - -// When we cancel a write/truncate, we always get back the result of the write -// before the result of the cancel, no matter what happens. -// So we'll get back either -// success [of the write/truncate, in a DidWrite(XXX, true)/DidSucceed() call] -// followed by failure [of the cancel]; or -// failure [of the write, either from cancel or other reasons] followed by -// the result of the cancel. -// In the write case, there could also be queued up non-terminal DidWrite calls -// before any of that comes back, but there will always be a terminal write -// response [success or failure] after them, followed by the cancel result, so -// we can ignore non-terminal write responses, take the terminal write success -// or the first failure as the last write response, then know that the next -// thing to come back is the cancel response. We only notify the -// AsyncFileWriterClient when it's all over. -void WebFileWriterImpl::cancel() { - DCHECK(kOperationWrite == operation_ || kOperationTruncate == operation_); - if (kCancelNotInProgress != cancel_state_) - return; - cancel_state_ = kCancelSent; - FileSystemDispatcher* dispatcher = - ChildThread::current()->file_system_dispatcher(); - dispatcher->Cancel( - request_id_, new FileSystemCallbackDispatcherImpl(AsWeakPtr())); -} - -void WebFileWriterImpl::DidSucceed() { - // Write never gets a DidSucceed call, so this is either a cancel or truncate - // response. - switch (cancel_state_) { - case kCancelNotInProgress: - // A truncate succeeded, with no complications. - DCHECK(kOperationTruncate == operation_); - operation_ = kOperationNone; - client_->didTruncate(); - break; - case kCancelSent: - DCHECK(kOperationTruncate == operation_); - // This is the success call of the truncate, which we'll eat, even though - // it succeeded before the cancel got there. We accepted the cancel call, - // so the truncate will eventually return an error. - cancel_state_ = kCancelReceivedWriteResponse; - break; - case kCancelReceivedWriteResponse: - // This is the success of the cancel operation. - FinishCancel(); - break; - default: - NOTREACHED(); - } -} - -void WebFileWriterImpl::DidFail(base::PlatformFileError error_code) { - DCHECK(kOperationNone != operation_); - switch (cancel_state_) { - case kCancelNotInProgress: - // A write or truncate failed. - operation_ = kOperationNone; - client_->didFail( - webkit_glue::PlatformFileErrorToWebFileError(error_code)); - break; - case kCancelSent: - // This is the failure of a write or truncate; the next message should be - // the result of the cancel. We don't assume that it'll be a success, as - // the write/truncate could have failed for other reasons. - cancel_state_ = kCancelReceivedWriteResponse; - break; - case kCancelReceivedWriteResponse: - // The cancel reported failure, meaning that the write or truncate - // finished before the cancel got there. But we suppressed the - // write/truncate's response, and will now report that it was cancelled. - FinishCancel(); - break; - default: - NOTREACHED(); - } +void WebFileWriterImpl::DoTruncate(const FilePath& path, int64 offset) { + // The FileSystemDispatcher takes ownership of the CallbackDispatcher. + GetFileSystemDispatcher()->Truncate(path, offset, &request_id_, + new CallbackDispatcher(AsWeakPtr())); } -void WebFileWriterImpl::DidWrite(int64 bytes, bool complete) { - DCHECK(kOperationWrite == operation_); - switch (cancel_state_) { - case kCancelNotInProgress: - if (complete) - operation_ = kOperationNone; - client_->didWrite(bytes, complete); - break; - case kCancelSent: - // This is the success call of the write, which we'll eat, even though - // it succeeded before the cancel got there. We accepted the cancel call, - // so the write will eventually return an error. - if (complete) - cancel_state_ = kCancelReceivedWriteResponse; - break; - case kCancelReceivedWriteResponse: - default: - NOTREACHED(); - } +void WebFileWriterImpl::DoWrite( + const FilePath& path, const GURL& blob_url, int64 offset) { + GetFileSystemDispatcher()->Write(path, blob_url, offset, &request_id_, + new CallbackDispatcher(AsWeakPtr())); } -void WebFileWriterImpl::FinishCancel() { - DCHECK(kCancelReceivedWriteResponse == cancel_state_); - DCHECK(kOperationNone != operation_); - cancel_state_ = kCancelNotInProgress; - operation_ = kOperationNone; - client_->didFail(WebKit::WebFileErrorAbort); +void WebFileWriterImpl::DoCancel() { + GetFileSystemDispatcher()->Cancel(request_id_, + new CallbackDispatcher(AsWeakPtr())); } diff --git a/chrome/common/file_system/webfilewriter_impl.h b/chrome/common/file_system/webfilewriter_impl.h index 6f1c0a7..9c9edb5 100644 --- a/chrome/common/file_system/webfilewriter_impl.h +++ b/chrome/common/file_system/webfilewriter_impl.h @@ -5,54 +5,30 @@ #ifndef CHROME_COMMON_FILE_SYSTEM_WEBFILEWRITER_IMPL_H_ #define CHROME_COMMON_FILE_SYSTEM_WEBFILEWRITER_IMPL_H_ -#include "base/basictypes.h" +#include "base/ref_counted.h" #include "base/weak_ptr.h" -#include "chrome/common/file_system/file_system_dispatcher.h" -#include "third_party/WebKit/WebKit/chromium/public/WebFileWriter.h" +#include "webkit/fileapi/webfilewriter_base.h" -namespace WebKit { -class WebFileWriterClient; -class WebString; -class WebURL; -} +class FileSystemDispatcher; -class WebFileWriterImpl - : public WebKit::WebFileWriter, - public base::SupportsWeakPtr<WebFileWriterImpl> { +// An implementation of WebFileWriter for use in chrome renderers and workers. +class WebFileWriterImpl : public fileapi::WebFileWriterBase, + public base::SupportsWeakPtr<WebFileWriterImpl> { public: WebFileWriterImpl( const WebKit::WebString& path, WebKit::WebFileWriterClient* client); virtual ~WebFileWriterImpl(); - // WebFileWriter implementation - virtual void truncate(long long length); - virtual void write(long long position, const WebKit::WebURL& blobURL); - virtual void cancel(); + protected: + // WebFileWriterBase overrides + virtual void DoTruncate(const FilePath& path, int64 offset); + virtual void DoWrite(const FilePath& path, const GURL& blob_url, + int64 offset); + virtual void DoCancel(); private: - class FileSystemCallbackDispatcherImpl; - enum OperationType { - kOperationNone, - kOperationWrite, - kOperationTruncate - }; - - enum CancelState { - kCancelNotInProgress, - kCancelSent, - kCancelReceivedWriteResponse, - }; - - void DidSucceed(); - void DidFail(base::PlatformFileError error_code); - void DidWrite(int64 bytes, bool complete); - void FinishCancel(); - - FilePath path_; - WebKit::WebFileWriterClient* client_; + class CallbackDispatcher; int request_id_; - OperationType operation_; - CancelState cancel_state_; }; #endif // CHROME_COMMON_FILE_SYSTEM_WEBFILEWRITER_IMPL_H_ diff --git a/webkit/fileapi/file_system_callback_dispatcher.h b/webkit/fileapi/file_system_callback_dispatcher.h index e33dd69..ea7c442 100644 --- a/webkit/fileapi/file_system_callback_dispatcher.h +++ b/webkit/fileapi/file_system_callback_dispatcher.h @@ -16,6 +16,8 @@ namespace fileapi { // but uses chromium types. class FileSystemCallbackDispatcher { public: + virtual ~FileSystemCallbackDispatcher() {} + // Callback for various operations that don't require return values. virtual void DidSucceed() = 0; diff --git a/webkit/fileapi/webfilewriter_base.cc b/webkit/fileapi/webfilewriter_base.cc new file mode 100644 index 0000000..9d3939f --- /dev/null +++ b/webkit/fileapi/webfilewriter_base.cc @@ -0,0 +1,145 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/fileapi/webfilewriter_base.h" + +#include "base/logging.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileError.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileWriterClient.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURL.h" +#include "webkit/glue/webkit_glue.h" + +namespace fileapi { + +WebFileWriterBase::WebFileWriterBase( + const WebKit::WebString& path, WebKit::WebFileWriterClient* client) + : path_(webkit_glue::WebStringToFilePath(path)), + client_(client), + operation_(kOperationNone), + cancel_state_(kCancelNotInProgress) { +} + +WebFileWriterBase::~WebFileWriterBase() { +} + +void WebFileWriterBase::truncate(long long length) { + DCHECK(kOperationNone == operation_); + DCHECK(kCancelNotInProgress == cancel_state_); + operation_ = kOperationTruncate; + DoTruncate(path_, length); +} + +void WebFileWriterBase::write( + long long position, + const WebKit::WebURL& blob_url) { + DCHECK(kOperationNone == operation_); + DCHECK(kCancelNotInProgress == cancel_state_); + operation_ = kOperationWrite; + DoWrite(path_, blob_url, position); +} + +// When we cancel a write/truncate, we always get back the result of the write +// before the result of the cancel, no matter what happens. +// So we'll get back either +// success [of the write/truncate, in a DidWrite(XXX, true)/DidSucceed() call] +// followed by failure [of the cancel]; or +// failure [of the write, either from cancel or other reasons] followed by +// the result of the cancel. +// In the write case, there could also be queued up non-terminal DidWrite calls +// before any of that comes back, but there will always be a terminal write +// response [success or failure] after them, followed by the cancel result, so +// we can ignore non-terminal write responses, take the terminal write success +// or the first failure as the last write response, then know that the next +// thing to come back is the cancel response. We only notify the +// AsyncFileWriterClient when it's all over. +void WebFileWriterBase::cancel() { + DCHECK(kOperationWrite == operation_ || kOperationTruncate == operation_); + if (kCancelNotInProgress != cancel_state_) + return; + cancel_state_ = kCancelSent; + DoCancel(); +} + +void WebFileWriterBase::DidSucceed() { + // Write never gets a DidSucceed call, so this is either a cancel or truncate + // response. + switch (cancel_state_) { + case kCancelNotInProgress: + // A truncate succeeded, with no complications. + DCHECK(kOperationTruncate == operation_); + operation_ = kOperationNone; + client_->didTruncate(); + break; + case kCancelSent: + DCHECK(kOperationTruncate == operation_); + // This is the success call of the truncate, which we'll eat, even though + // it succeeded before the cancel got there. We accepted the cancel call, + // so the truncate will eventually return an error. + cancel_state_ = kCancelReceivedWriteResponse; + break; + case kCancelReceivedWriteResponse: + // This is the success of the cancel operation. + FinishCancel(); + break; + default: + NOTREACHED(); + } +} + +void WebFileWriterBase::DidFail(base::PlatformFileError error_code) { + DCHECK(kOperationNone != operation_); + switch (cancel_state_) { + case kCancelNotInProgress: + // A write or truncate failed. + operation_ = kOperationNone; + client_->didFail( + webkit_glue::PlatformFileErrorToWebFileError(error_code)); + break; + case kCancelSent: + // This is the failure of a write or truncate; the next message should be + // the result of the cancel. We don't assume that it'll be a success, as + // the write/truncate could have failed for other reasons. + cancel_state_ = kCancelReceivedWriteResponse; + break; + case kCancelReceivedWriteResponse: + // The cancel reported failure, meaning that the write or truncate + // finished before the cancel got there. But we suppressed the + // write/truncate's response, and will now report that it was cancelled. + FinishCancel(); + break; + default: + NOTREACHED(); + } +} + +void WebFileWriterBase::DidWrite(int64 bytes, bool complete) { + DCHECK(kOperationWrite == operation_); + switch (cancel_state_) { + case kCancelNotInProgress: + if (complete) + operation_ = kOperationNone; + client_->didWrite(bytes, complete); + break; + case kCancelSent: + // This is the success call of the write, which we'll eat, even though + // it succeeded before the cancel got there. We accepted the cancel call, + // so the write will eventually return an error. + if (complete) + cancel_state_ = kCancelReceivedWriteResponse; + break; + case kCancelReceivedWriteResponse: + default: + NOTREACHED(); + } +} + +void WebFileWriterBase::FinishCancel() { + DCHECK(kCancelReceivedWriteResponse == cancel_state_); + DCHECK(kOperationNone != operation_); + cancel_state_ = kCancelNotInProgress; + operation_ = kOperationNone; + client_->didFail(WebKit::WebFileErrorAbort); +} + +} // namespace fileapi diff --git a/webkit/fileapi/webfilewriter_base.h b/webkit/fileapi/webfilewriter_base.h new file mode 100644 index 0000000..790e48b --- /dev/null +++ b/webkit/fileapi/webfilewriter_base.h @@ -0,0 +1,69 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_FILEAPI_WEBFILEWRITER_BASE_H_ +#define WEBKIT_FILEAPI_WEBFILEWRITER_BASE_H_ + +#include "base/file_path.h" +#include "base/platform_file.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileWriter.h" + +class GURL; + +namespace WebKit { +class WebFileWriterClient; +class WebString; +class WebURL; +} + +namespace fileapi { + +class WebFileWriterBase : public WebKit::WebFileWriter { + public: + WebFileWriterBase( + const WebKit::WebString& path, WebKit::WebFileWriterClient* client); + virtual ~WebFileWriterBase(); + + // WebFileWriter implementation + virtual void truncate(long long length); + virtual void write(long long position, const WebKit::WebURL& blobURL); + virtual void cancel(); + + protected: + // Derived classes must provide these methods to asynchronously perform + // the requested operation, and they must call the appropiate DidSomething + // method upon completion and as progress is made in the Write case. + virtual void DoTruncate(const FilePath& path, int64 offset) = 0; + virtual void DoWrite(const FilePath& path, const GURL& blob_url, + int64 offset) = 0; + virtual void DoCancel() = 0; + + void DidSucceed(); + void DidFail(base::PlatformFileError error_code); + void DidWrite(int64 bytes, bool complete); + + private: + enum OperationType { + kOperationNone, + kOperationWrite, + kOperationTruncate + }; + + enum CancelState { + kCancelNotInProgress, + kCancelSent, + kCancelReceivedWriteResponse, + }; + + void FinishCancel(); + + FilePath path_; + WebKit::WebFileWriterClient* client_; + OperationType operation_; + CancelState cancel_state_; +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_WEBFILEWRITER_BASE_H_ diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi index 5189564..73d49838 100644 --- a/webkit/fileapi/webkit_fileapi.gypi +++ b/webkit/fileapi/webkit_fileapi.gypi @@ -24,6 +24,8 @@ 'file_system_types.h', 'file_writer_delegate.cc', 'file_writer_delegate.h', + 'webfilewriter_base.cc', + 'webfilewriter_base.h', ], 'conditions': [ ['inside_chromium_build==0', { diff --git a/webkit/support/webkit_support.gypi b/webkit/support/webkit_support.gypi index 99c8ae0..05dd565 100644 --- a/webkit/support/webkit_support.gypi +++ b/webkit/support/webkit_support.gypi @@ -54,6 +54,8 @@ '<(DEPTH)/webkit/tools/test_shell/simple_appcache_system.h', '<(DEPTH)/webkit/tools/test_shell/simple_file_system.cc', '<(DEPTH)/webkit/tools/test_shell/simple_file_system.h', + '<(DEPTH)/webkit/tools/test_shell/simple_file_writer.cc', + '<(DEPTH)/webkit/tools/test_shell/simple_file_writer.h', '<(DEPTH)/webkit/tools/test_shell/simple_clipboard_impl.cc', '<(DEPTH)/webkit/tools/test_shell/simple_database_system.cc', '<(DEPTH)/webkit/tools/test_shell/simple_database_system.h', diff --git a/webkit/tools/test_shell/simple_file_system.cc b/webkit/tools/test_shell/simple_file_system.cc index 411d987..ae77ce4 100644 --- a/webkit/tools/test_shell/simple_file_system.cc +++ b/webkit/tools/test_shell/simple_file_system.cc @@ -12,10 +12,13 @@ #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" #include "webkit/fileapi/file_system_callback_dispatcher.h" #include "webkit/glue/webkit_glue.h" +#include "webkit/tools/test_shell/simple_file_writer.h" using WebKit::WebFileInfo; using WebKit::WebFileSystemCallbacks; using WebKit::WebFileSystemEntry; +using WebKit::WebFileWriter; +using WebKit::WebFileWriterClient; using WebKit::WebString; using WebKit::WebVector; @@ -61,7 +64,10 @@ class TestShellFileSystemCallbackDispatcher virtual void DidReadMetadata(const base::PlatformFileInfo& info) { WebFileInfo web_file_info; + web_file_info.length = info.size; web_file_info.modificationTime = info.last_modified.ToDoubleT(); + web_file_info.type = info.is_directory ? + WebFileInfo::TypeDirectory : WebFileInfo::TypeFile; callbacks_->didReadMetadata(web_file_info); file_system_->RemoveCompletedOperation(request_id_); } @@ -165,7 +171,7 @@ void SimpleFileSystem::createDirectory( } void SimpleFileSystem::fileExists( - const WebString& path, WebFileSystemCallbacks* callbacks) { + const WebString& path, WebFileSystemCallbacks* callbacks) { FilePath filepath(webkit_glue::WebStringToFilePath(path)); GetNewOperation(callbacks)->FileExists(filepath); @@ -185,6 +191,11 @@ void SimpleFileSystem::readDirectory( GetNewOperation(callbacks)->ReadDirectory(filepath); } +WebFileWriter* SimpleFileSystem::createFileWriter( + const WebString& path, WebFileWriterClient* client) { + return new SimpleFileWriter(path, client); +} + fileapi::FileSystemOperation* SimpleFileSystem::GetNewOperation( WebFileSystemCallbacks* callbacks) { // This pointer will be owned by |operation|. diff --git a/webkit/tools/test_shell/simple_file_system.h b/webkit/tools/test_shell/simple_file_system.h index 031ed8b..e1a8236 100644 --- a/webkit/tools/test_shell/simple_file_system.h +++ b/webkit/tools/test_shell/simple_file_system.h @@ -44,6 +44,8 @@ class SimpleFileSystem : public WebKit::WebFileSystem { WebKit::WebFileSystemCallbacks* callbacks); virtual void readDirectory(const WebKit::WebString& path, WebKit::WebFileSystemCallbacks* callbacks); + virtual WebKit::WebFileWriter* createFileWriter( + const WebKit::WebString& path, WebKit::WebFileWriterClient* client); private: // Helpers. diff --git a/webkit/tools/test_shell/simple_file_writer.cc b/webkit/tools/test_shell/simple_file_writer.cc new file mode 100644 index 0000000..0c1a434 --- /dev/null +++ b/webkit/tools/test_shell/simple_file_writer.cc @@ -0,0 +1,186 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/tools/test_shell/simple_file_writer.h" + +#include "base/logging.h" +#include "base/message_loop_proxy.h" +#include "net/url_request/url_request_context.h" +#include "webkit/fileapi/file_system_callback_dispatcher.h" +#include "webkit/fileapi/file_system_operation.h" +#include "webkit/glue/webkit_glue.h" +#include "webkit/tools/test_shell/simple_resource_loader_bridge.h" + +using fileapi::FileSystemOperation; +using fileapi::FileSystemCallbackDispatcher; +using fileapi::WebFileWriterBase; +using WebKit::WebFileWriterClient; +using WebKit::WebString; +using WebKit::WebURL; + +URLRequestContext* SimpleFileWriter::request_context_ = NULL; + +// Helper class to proxy to write and truncate calls to the IO thread, +// and to proxy the results back to the main thead. There is a one-to-one +// relationship between SimpleFileWriters and IOThreadBackends. +class SimpleFileWriter::IOThreadProxy + : public base::RefCountedThreadSafe<SimpleFileWriter::IOThreadProxy> { + public: + explicit IOThreadProxy(const base::WeakPtr<SimpleFileWriter>& simple_writer) + : simple_writer_(simple_writer) { + // The IO thread needs to be running for this class to work. + SimpleResourceLoaderBridge::EnsureIOThread(); + io_thread_ = SimpleResourceLoaderBridge::GetIoThread(); + main_thread_ = base::MessageLoopProxy::CreateForCurrentThread(); + } + + virtual ~IOThreadProxy() { + } + + void Truncate(const FilePath& path, int64 offset) { + if (!io_thread_->BelongsToCurrentThread()) { + io_thread_->PostTask(FROM_HERE, NewRunnableMethod( + this, &IOThreadProxy::Truncate, path, offset)); + return; + } + DCHECK(!operation_.get()); + operation_.reset(GetNewOperation()); + operation_->Truncate(path, offset); + } + + void Write(const FilePath& path, const GURL& blob_url, int64 offset) { + if (!io_thread_->BelongsToCurrentThread()) { + io_thread_->PostTask(FROM_HERE, NewRunnableMethod( + this, &IOThreadProxy::Write, path, blob_url, offset)); + return; + } + DCHECK(request_context_); + DCHECK(!operation_.get()); + operation_.reset(GetNewOperation()); + operation_->Write(request_context_, path, blob_url, offset); + } + + void Cancel() { + if (!io_thread_->BelongsToCurrentThread()) { + io_thread_->PostTask(FROM_HERE, NewRunnableMethod( + this, &IOThreadProxy::Cancel)); + return; + } + if (!operation_.get()) { + DidFail(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); + return; + } + cancel_operation_.reset(GetNewOperation()); + operation_->Cancel(cancel_operation_.get()); + } + + private: + // Inner class to receive callbacks from FileSystemOperation. + class CallbackDispatcher : public FileSystemCallbackDispatcher { + public: + explicit CallbackDispatcher(IOThreadProxy* proxy) : proxy_(proxy) { + } + + virtual void DidSucceed() { + proxy_->DidSucceed(); + } + + virtual void DidFail(base::PlatformFileError error_code) { + proxy_->DidFail(error_code); + } + + virtual void DidWrite(int64 bytes, bool complete) { + proxy_->DidWrite(bytes, complete); + } + + virtual void DidReadMetadata(const base::PlatformFileInfo&) { + NOTREACHED(); + } + + virtual void DidReadDirectory( + const std::vector<base::file_util_proxy::Entry>& entries, + bool has_more) { + NOTREACHED(); + } + + virtual void DidOpenFileSystem(const std::string& name, + const FilePath& root_path) { + NOTREACHED(); + } + + scoped_refptr<IOThreadProxy> proxy_; + }; + + FileSystemOperation* GetNewOperation() { + // The FileSystemOperation takes ownership of the CallbackDispatcher. + return new FileSystemOperation(new CallbackDispatcher(this), io_thread_); + } + + void DidSucceed() { + if (!main_thread_->BelongsToCurrentThread()) { + operation_.reset(); + main_thread_->PostTask(FROM_HERE, NewRunnableMethod( + this, &IOThreadProxy::DidSucceed)); + return; + } + if (simple_writer_) + simple_writer_->DidSucceed(); + } + + void DidFail(base::PlatformFileError error_code) { + if (!main_thread_->BelongsToCurrentThread()) { + operation_.reset(); + main_thread_->PostTask(FROM_HERE, NewRunnableMethod( + this, &IOThreadProxy::DidFail, error_code)); + return; + } + if (simple_writer_) + simple_writer_->DidFail(error_code); + } + + void DidWrite(int64 bytes, bool complete) { + if (!main_thread_->BelongsToCurrentThread()) { + if (complete) + operation_.reset(); + main_thread_->PostTask(FROM_HERE, NewRunnableMethod( + this, &IOThreadProxy::DidWrite, bytes, complete)); + return; + } + if (simple_writer_) + simple_writer_->DidWrite(bytes, complete); + } + + scoped_refptr<base::MessageLoopProxy> io_thread_; + scoped_refptr<base::MessageLoopProxy> main_thread_; + + // Only used on the main thread. + base::WeakPtr<SimpleFileWriter> simple_writer_; + + // Only used on the io thread. + scoped_ptr<FileSystemOperation> operation_; + scoped_ptr<FileSystemOperation> cancel_operation_; +}; + + +SimpleFileWriter::SimpleFileWriter( + const WebString& path, WebFileWriterClient* client) + : WebFileWriterBase(path, client), + io_thread_proxy_(new IOThreadProxy(AsWeakPtr())) { +} + +SimpleFileWriter::~SimpleFileWriter() { +} + +void SimpleFileWriter::DoTruncate(const FilePath& path, int64 offset) { + io_thread_proxy_->Truncate(path, offset); +} + +void SimpleFileWriter::DoWrite( + const FilePath& path, const GURL& blob_url, int64 offset) { + io_thread_proxy_->Write(path, blob_url, offset); +} + +void SimpleFileWriter::DoCancel() { + io_thread_proxy_->Cancel(); +} diff --git a/webkit/tools/test_shell/simple_file_writer.h b/webkit/tools/test_shell/simple_file_writer.h new file mode 100644 index 0000000..285fc02 --- /dev/null +++ b/webkit/tools/test_shell/simple_file_writer.h @@ -0,0 +1,45 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBKIT_TOOLS_TEST_SHELL_SIMPLE_FILE_WRITER_H_ +#define WEBKIT_TOOLS_TEST_SHELL_SIMPLE_FILE_WRITER_H_ + +#include "base/ref_counted.h" +#include "base/weak_ptr.h" +#include "webkit/fileapi/webfilewriter_base.h" + +class URLRequestContext; + + +// An implementation of WebFileWriter for use in test_shell and DRT. +class SimpleFileWriter : public fileapi::WebFileWriterBase, + public base::SupportsWeakPtr<SimpleFileWriter> { + public: + SimpleFileWriter( + const WebKit::WebString& path, WebKit::WebFileWriterClient* client); + virtual ~SimpleFileWriter(); + + // Called by SimpleResourceLoaderBridge when the context is + // created and destroyed. + static void InitializeOnIOThread(URLRequestContext* request_context) { + request_context_ = request_context; + } + static void CleanupOnIOThread() { + request_context_ = NULL; + } + + protected: + // WebFileWriterBase overrides + virtual void DoTruncate(const FilePath& path, int64 offset); + virtual void DoWrite(const FilePath& path, const GURL& blob_url, + int64 offset); + virtual void DoCancel(); + + private: + class IOThreadProxy; + scoped_refptr<IOThreadProxy> io_thread_proxy_; + static URLRequestContext* request_context_; +}; + +#endif // WEBKIT_TOOLS_TEST_SHELL_SIMPLE_FILE_WRITER_H_ diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index a4ef5e7..954b258 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -68,6 +68,7 @@ #include "webkit/blob/deletable_file_reference.h" #include "webkit/glue/resource_loader_bridge.h" #include "webkit/tools/test_shell/simple_appcache_system.h" +#include "webkit/tools/test_shell/simple_file_writer.h" #include "webkit/tools/test_shell/simple_socket_stream_bridge.h" #include "webkit/tools/test_shell/test_shell_request_context.h" #include "webkit/tools/test_shell/test_shell_webblobregistry_impl.h" @@ -142,6 +143,7 @@ class IOThread : public base::Thread { SimpleAppCacheSystem::InitializeOnIOThread(g_request_context); SimpleSocketStreamBridge::InitializeOnIOThread(g_request_context); + SimpleFileWriter::InitializeOnIOThread(g_request_context); TestShellWebBlobRegistryImpl::InitializeOnIOThread( static_cast<TestShellRequestContext*>(g_request_context)-> @@ -152,6 +154,7 @@ class IOThread : public base::Thread { virtual void CleanUp() { SimpleSocketStreamBridge::Cleanup(); TestShellWebBlobRegistryImpl::Cleanup(); + SimpleFileWriter::CleanupOnIOThread(); if (g_request_context) { g_request_context->Release(); g_request_context = NULL; diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc index 41bf9d3..5727cab 100644 --- a/webkit/tools/test_shell/test_webview_delegate.cc +++ b/webkit/tools/test_shell/test_webview_delegate.cc @@ -1126,6 +1126,7 @@ void TestWebViewDelegate::openFileSystem( // The FileSystem temp directory was not initialized successfully. callbacks->didFail(WebKit::WebFileErrorSecurity); } else { + // TODO(michaeln): need to put origin/type in the path. callbacks->didOpenFileSystem( "TestShellFileSystem", webkit_glue::FilePathToWebString(shell_->file_system_root())); |