diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-22 09:19:31 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-22 09:19:31 +0000 |
commit | 397a1f4db17560722bcb45108ccf7bf07fd5139f (patch) | |
tree | 4527d92f136e2e32c2cea613e69e1cd468cab89a /webkit/fileapi/file_writer_delegate.cc | |
parent | 1adcd7531107e881f31ce3f1cb18a87d94935347 (diff) | |
download | chromium_src-397a1f4db17560722bcb45108ccf7bf07fd5139f.zip chromium_src-397a1f4db17560722bcb45108ccf7bf07fd5139f.tar.gz chromium_src-397a1f4db17560722bcb45108ccf7bf07fd5139f.tar.bz2 |
Implement SandboxFileWriter and rewrite FileWriterDelegate to use it
BUG=127529
TEST=FileWriterDelegate*, FileSystemOperationWrite*
Review URL: https://chromiumcodereview.appspot.com/10387054
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138236 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi/file_writer_delegate.cc')
-rw-r--r-- | webkit/fileapi/file_writer_delegate.cc | 192 |
1 files changed, 33 insertions, 159 deletions
diff --git a/webkit/fileapi/file_writer_delegate.cc b/webkit/fileapi/file_writer_delegate.cc index 283cbe0..d8c33ba 100644 --- a/webkit/fileapi/file_writer_delegate.cc +++ b/webkit/fileapi/file_writer_delegate.cc @@ -13,9 +13,7 @@ #include "base/threading/thread_restrictions.h" #include "net/base/net_errors.h" #include "webkit/fileapi/file_system_context.h" -#include "webkit/fileapi/file_system_operation.h" -#include "webkit/fileapi/file_system_operation_context.h" -#include "webkit/fileapi/file_system_quota_util.h" +#include "webkit/fileapi/file_writer.h" namespace fileapi { @@ -23,70 +21,30 @@ static const int kReadBufSize = 32768; namespace { -typedef base::Callback<void(base::PlatformFileError /* error code */, - const base::PlatformFileInfo& /* file_info */)> - InitializeTaskCallback; - -class InitializeTask : public base::RefCountedThreadSafe<InitializeTask> { - public: - InitializeTask( - base::PlatformFile file, - const InitializeTaskCallback& callback) - : original_loop_(base::MessageLoopProxy::current()), - error_code_(base::PLATFORM_FILE_OK), - file_(file), - callback_(callback) { - DCHECK_EQ(false, callback.is_null()); - } - - bool Start(base::SequencedTaskRunner* task_runner, - const tracked_objects::Location& from_here) { - return task_runner->PostTask( - from_here, - base::Bind(&InitializeTask::ProcessOnTargetThread, this)); - } - - private: - friend class base::RefCountedThreadSafe<InitializeTask>; - ~InitializeTask() {} - - void RunCallback() { - callback_.Run(error_code_, file_info_); +base::PlatformFileError NetErrorToPlatformFileError(int error) { +// TODO(kinuko): Move this static method to more convenient place. + switch (error) { + case net::ERR_FILE_NO_SPACE: + return base::PLATFORM_FILE_ERROR_NO_SPACE; + case net::ERR_FILE_NOT_FOUND: + return base::PLATFORM_FILE_ERROR_NOT_FOUND; + case net::ERR_ACCESS_DENIED: + return base::PLATFORM_FILE_ERROR_ACCESS_DENIED; + default: + return base::PLATFORM_FILE_ERROR_FAILED; } +} - void ProcessOnTargetThread() { - if (!base::GetPlatformFileInfo(file_, &file_info_)) - error_code_ = base::PLATFORM_FILE_ERROR_FAILED; - original_loop_->PostTask( - FROM_HERE, - base::Bind(&InitializeTask::RunCallback, this)); - } - - scoped_refptr<base::MessageLoopProxy> original_loop_; - base::PlatformFileError error_code_; - - base::PlatformFile file_; - InitializeTaskCallback callback_; - - base::PlatformFileInfo file_info_; -}; - -} // namespace (anonymous) +} // namespace FileWriterDelegate::FileWriterDelegate( - FileSystemOperation* file_system_operation, - const FileSystemPath& path, - int64 offset) - : file_system_operation_(file_system_operation), - file_(base::kInvalidPlatformFileValue), - path_(path), - offset_(offset), - has_pending_write_(false), + const FileSystemOperationInterface::WriteCallback& write_callback, + scoped_ptr<FileWriter> file_writer) + : write_callback_(write_callback), + file_writer_(file_writer.Pass()), bytes_written_backlog_(0), bytes_written_(0), bytes_read_(0), - total_bytes_written_(0), - allowed_bytes_to_write_(0), io_buffer_(new net::IOBufferWithSize(kReadBufSize)), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { } @@ -94,44 +52,11 @@ FileWriterDelegate::FileWriterDelegate( FileWriterDelegate::~FileWriterDelegate() { } -void FileWriterDelegate::OnGetFileInfoAndStartRequest( - scoped_ptr<net::URLRequest> request, - base::PlatformFileError error, - const base::PlatformFileInfo& file_info) { - if (error != base::PLATFORM_FILE_OK) { - OnError(error); - return; - } - int64 allowed_bytes_growth = - file_system_operation_context()->allowed_bytes_growth(); - if (allowed_bytes_growth < 0) - allowed_bytes_growth = 0; - int64 overlap = file_info.size - offset_; - allowed_bytes_to_write_ = allowed_bytes_growth; - if (kint64max - overlap > allowed_bytes_growth) - allowed_bytes_to_write_ += overlap; - size_ = file_info.size; - file_stream_.reset(new net::FileStream( - file_, - base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE | - base::PLATFORM_FILE_ASYNC, - NULL)); - DCHECK(!request_.get()); +void FileWriterDelegate::Start(scoped_ptr<net::URLRequest> request) { request_ = request.Pass(); request_->Start(); } -void FileWriterDelegate::Start(base::PlatformFile file, - scoped_ptr<net::URLRequest> request) { - file_ = file; - - scoped_refptr<InitializeTask> relay = new InitializeTask( - file_, - base::Bind(&FileWriterDelegate::OnGetFileInfoAndStartRequest, - weak_factory_.GetWeakPtr(), base::Passed(&request))); - relay->Start(file_system_operation_context()->file_task_runner(), FROM_HERE); -} - bool FileWriterDelegate::Cancel() { if (request_.get()) { // This halts any callbacks on this delegate. @@ -139,9 +64,12 @@ bool FileWriterDelegate::Cancel() { request_->Cancel(); } - // Return true to finish immediately if we're not writing. - // Otherwise we'll do the final cleanup in the write callback. - return !has_pending_write_; + const int status = file_writer_->Cancel( + base::Bind(&FileWriterDelegate::OnWriteCancelled, + weak_factory_.GetWeakPtr())); + // Return true to finish immediately if we have no pending writes. + // Otherwise we'll do the final cleanup in the Cancel callback. + return (status != net::ERR_IO_PENDING); } void FileWriterDelegate::OnReceivedRedirect(net::URLRequest* request, @@ -173,18 +101,10 @@ void FileWriterDelegate::OnSSLCertificateError(net::URLRequest* request, void FileWriterDelegate::OnResponseStarted(net::URLRequest* request) { DCHECK_EQ(request_.get(), request); - // file_stream_->Seek() blocks the IO thread. - // See http://crbug.com/75548. - base::ThreadRestrictions::ScopedAllowIO allow_io; if (!request->status().is_success() || request->GetResponseCode() != 200) { OnError(base::PLATFORM_FILE_ERROR_FAILED); return; } - int64 error = file_stream_->SeekSync(net::FROM_BEGIN, offset_); - if (error != offset_) { - OnError(base::PLATFORM_FILE_ERROR_FAILED); - return; - } Read(); } @@ -201,8 +121,7 @@ void FileWriterDelegate::OnReadCompleted(net::URLRequest* request, void FileWriterDelegate::Read() { bytes_written_ = 0; bytes_read_ = 0; - if (request_->Read(io_buffer_.get(), io_buffer_->size(), - &bytes_read_)) { + if (request_->Read(io_buffer_.get(), io_buffer_->size(), &bytes_read_)) { MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&FileWriterDelegate::OnDataReceived, @@ -226,24 +145,9 @@ void FileWriterDelegate::OnDataReceived(int bytes_read) { } void FileWriterDelegate::Write() { - // allowed_bytes_to_write could be negative if the file size is - // greater than the current (possibly new) quota. - // (The UI should clear the entire origin data if the smaller quota size - // is set in general, though the UI/deletion code is not there yet.) - DCHECK(total_bytes_written_ <= allowed_bytes_to_write_ || - allowed_bytes_to_write_ < 0); - if (total_bytes_written_ >= allowed_bytes_to_write_) { - OnError(base::PLATFORM_FILE_ERROR_NO_SPACE); - return; - } - int64 bytes_to_write = bytes_read_ - bytes_written_; - if (bytes_to_write > allowed_bytes_to_write_ - total_bytes_written_) - bytes_to_write = allowed_bytes_to_write_ - total_bytes_written_; - - has_pending_write_ = true; int write_response = - file_stream_->Write(cursor_, + file_writer_->Write(cursor_, static_cast<int>(bytes_to_write), base::Bind(&FileWriterDelegate::OnDataWritten, weak_factory_.GetWeakPtr())); @@ -253,26 +157,20 @@ void FileWriterDelegate::Write() { base::Bind(&FileWriterDelegate::OnDataWritten, weak_factory_.GetWeakPtr(), write_response)); else if (net::ERR_IO_PENDING != write_response) - OnError(base::PLATFORM_FILE_ERROR_FAILED); + OnError(NetErrorToPlatformFileError(write_response)); } void FileWriterDelegate::OnDataWritten(int write_response) { - has_pending_write_ = false; if (write_response > 0) { - if (request_->status().status() == net::URLRequestStatus::CANCELED) { - OnProgress(write_response, true); - return; - } OnProgress(write_response, false); cursor_->DidConsume(write_response); bytes_written_ += write_response; - total_bytes_written_ += write_response; if (bytes_written_ == bytes_read_) Read(); else Write(); } else { - OnError(base::PLATFORM_FILE_ERROR_FAILED); + OnError(NetErrorToPlatformFileError(write_response)); } } @@ -282,22 +180,11 @@ void FileWriterDelegate::OnError(base::PlatformFileError error) { request_->Cancel(); } - file_system_operation_->DidWrite(error, 0, true); + write_callback_.Run(error, 0, true); } void FileWriterDelegate::OnProgress(int bytes_written, bool done) { DCHECK(bytes_written + bytes_written_backlog_ >= bytes_written_backlog_); - if (quota_util() && - bytes_written > 0 && - total_bytes_written_ + bytes_written + offset_ > size_) { - int overlapped = 0; - if (total_bytes_written_ + offset_ < size_) - overlapped = size_ - total_bytes_written_ - offset_; - quota_util()->proxy()->UpdateOriginUsage( - file_system_operation_->file_system_context()->quota_manager_proxy(), - path_.origin(), path_.type(), - bytes_written - overlapped); - } static const int kMinProgressDelayMS = 200; base::Time currentTime = base::Time::Now(); if (done || last_progress_event_time_.is_null() || @@ -306,28 +193,15 @@ void FileWriterDelegate::OnProgress(int bytes_written, bool done) { bytes_written += bytes_written_backlog_; last_progress_event_time_ = currentTime; bytes_written_backlog_ = 0; - if (done && quota_util()) - quota_util()->proxy()->EndUpdateOrigin(path_.origin(), path_.type()); - file_system_operation_->DidWrite( + write_callback_.Run( base::PLATFORM_FILE_OK, bytes_written, done); return; } bytes_written_backlog_ += bytes_written; } -FileSystemOperationContext* -FileWriterDelegate::file_system_operation_context() const { - DCHECK(file_system_operation_); - DCHECK(file_system_operation_->file_system_operation_context()); - return file_system_operation_->file_system_operation_context(); -} - -FileSystemQuotaUtil* FileWriterDelegate::quota_util() const { - DCHECK(file_system_operation_); - DCHECK(file_system_operation_->file_system_context()); - DCHECK(file_system_operation_->file_system_operation_context()); - return file_system_operation_->file_system_context()->GetQuotaUtil( - path_.type()); +void FileWriterDelegate::OnWriteCancelled(int status) { + write_callback_.Run(base::PLATFORM_FILE_ERROR_ABORT, 0, true); } } // namespace fileapi |