| // Copyright 2013 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/browser/fileapi/file_system_operation_runner.h" |
| |
| #include "base/bind.h" |
| #include "base/message_loop/message_loop_proxy.h" |
| #include "base/stl_util.h" |
| #include "net/url_request/url_request_context.h" |
| #include "webkit/browser/blob/blob_url_request_job_factory.h" |
| #include "webkit/browser/fileapi/file_observers.h" |
| #include "webkit/browser/fileapi/file_stream_writer.h" |
| #include "webkit/browser/fileapi/file_system_context.h" |
| #include "webkit/browser/fileapi/file_system_operation.h" |
| #include "webkit/browser/fileapi/file_writer_delegate.h" |
| #include "webkit/common/blob/shareable_file_reference.h" |
| |
| namespace fileapi { |
| |
| typedef FileSystemOperationRunner::OperationID OperationID; |
| |
| class FileSystemOperationRunner::BeginOperationScoper |
| : public base::SupportsWeakPtr< |
| FileSystemOperationRunner::BeginOperationScoper> { |
| public: |
| BeginOperationScoper() {} |
| private: |
| DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper); |
| }; |
| |
| FileSystemOperationRunner::OperationHandle::OperationHandle() {} |
| FileSystemOperationRunner::OperationHandle::~OperationHandle() {} |
| |
| FileSystemOperationRunner::~FileSystemOperationRunner() { |
| } |
| |
| void FileSystemOperationRunner::Shutdown() { |
| operations_.Clear(); |
| } |
| |
| OperationID FileSystemOperationRunner::CreateFile( |
| const FileSystemURL& url, |
| bool exclusive, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForWrite(handle.id, url); |
| operation->CreateFile( |
| url, exclusive, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::CreateDirectory( |
| const FileSystemURL& url, |
| bool exclusive, |
| bool recursive, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForWrite(handle.id, url); |
| operation->CreateDirectory( |
| url, exclusive, recursive, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::Copy( |
| const FileSystemURL& src_url, |
| const FileSystemURL& dest_url, |
| CopyOrMoveOption option, |
| const CopyProgressCallback& progress_callback, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(dest_url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForWrite(handle.id, dest_url); |
| PrepareForRead(handle.id, src_url); |
| operation->Copy( |
| src_url, dest_url, option, |
| progress_callback.is_null() ? |
| CopyProgressCallback() : |
| base::Bind(&FileSystemOperationRunner::OnCopyProgress, AsWeakPtr(), |
| handle, progress_callback), |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::Move( |
| const FileSystemURL& src_url, |
| const FileSystemURL& dest_url, |
| CopyOrMoveOption option, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(dest_url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForWrite(handle.id, dest_url); |
| PrepareForWrite(handle.id, src_url); |
| operation->Move( |
| src_url, dest_url, option, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::DirectoryExists( |
| const FileSystemURL& url, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForRead(handle.id, url); |
| operation->DirectoryExists( |
| url, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::FileExists( |
| const FileSystemURL& url, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForRead(handle.id, url); |
| operation->FileExists( |
| url, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::GetMetadata( |
| const FileSystemURL& url, |
| const GetMetadataCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidGetMetadata(handle, callback, error, base::PlatformFileInfo()); |
| return handle.id; |
| } |
| PrepareForRead(handle.id, url); |
| operation->GetMetadata( |
| url, |
| base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::ReadDirectory( |
| const FileSystemURL& url, |
| const ReadDirectoryCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(), |
| false); |
| return handle.id; |
| } |
| PrepareForRead(handle.id, url); |
| operation->ReadDirectory( |
| url, |
| base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::Remove( |
| const FileSystemURL& url, bool recursive, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForWrite(handle.id, url); |
| operation->Remove( |
| url, recursive, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::Write( |
| const net::URLRequestContext* url_request_context, |
| const FileSystemURL& url, |
| scoped_ptr<webkit_blob::BlobDataHandle> blob, |
| int64 offset, |
| const WriteCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidWrite(handle, callback, error, 0, true); |
| return handle.id; |
| } |
| |
| scoped_ptr<FileStreamWriter> writer( |
| file_system_context_->CreateFileStreamWriter(url, offset)); |
| if (!writer) { |
| // Write is not supported. |
| DidWrite(handle, callback, base::PLATFORM_FILE_ERROR_SECURITY, 0, true); |
| return handle.id; |
| } |
| |
| scoped_ptr<FileWriterDelegate> writer_delegate( |
| new FileWriterDelegate(writer.Pass())); |
| |
| scoped_ptr<net::URLRequest> blob_request( |
| webkit_blob::BlobProtocolHandler::CreateBlobRequest( |
| blob.Pass(), |
| url_request_context, |
| writer_delegate.get())); |
| |
| PrepareForWrite(handle.id, url); |
| operation->Write( |
| url, writer_delegate.Pass(), blob_request.Pass(), |
| base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::Truncate( |
| const FileSystemURL& url, int64 length, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForWrite(handle.id, url); |
| operation->Truncate( |
| url, length, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| void FileSystemOperationRunner::Cancel( |
| OperationID id, |
| const StatusCallback& callback) { |
| if (ContainsKey(finished_operations_, id)) { |
| DCHECK(!ContainsKey(stray_cancel_callbacks_, id)); |
| stray_cancel_callbacks_[id] = callback; |
| return; |
| } |
| FileSystemOperation* operation = operations_.Lookup(id); |
| if (!operation) { |
| // There is no operation with |id|. |
| callback.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
| return; |
| } |
| operation->Cancel(callback); |
| } |
| |
| OperationID FileSystemOperationRunner::TouchFile( |
| const FileSystemURL& url, |
| const base::Time& last_access_time, |
| const base::Time& last_modified_time, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| PrepareForWrite(handle.id, url); |
| operation->TouchFile( |
| url, last_access_time, last_modified_time, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::OpenFile( |
| const FileSystemURL& url, |
| int file_flags, |
| const OpenFileCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidOpenFile(handle, callback, error, base::kInvalidPlatformFileValue, |
| base::Closure()); |
| return handle.id; |
| } |
| if (file_flags & |
| (base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_OPEN_ALWAYS | |
| base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_TRUNCATED | |
| base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_EXCLUSIVE_WRITE | |
| base::PLATFORM_FILE_DELETE_ON_CLOSE | |
| base::PLATFORM_FILE_WRITE_ATTRIBUTES)) { |
| PrepareForWrite(handle.id, url); |
| } else { |
| PrepareForRead(handle.id, url); |
| } |
| operation->OpenFile( |
| url, file_flags, |
| base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::CreateSnapshotFile( |
| const FileSystemURL& url, |
| const SnapshotFileCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidCreateSnapshot(handle, callback, error, base::PlatformFileInfo(), |
| base::FilePath(), NULL); |
| return handle.id; |
| } |
| PrepareForRead(handle.id, url); |
| operation->CreateSnapshotFile( |
| url, |
| base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::CopyInForeignFile( |
| const base::FilePath& src_local_disk_path, |
| const FileSystemURL& dest_url, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(dest_url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| operation->CopyInForeignFile( |
| src_local_disk_path, dest_url, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::RemoveFile( |
| const FileSystemURL& url, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| operation->RemoveFile( |
| url, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::RemoveDirectory( |
| const FileSystemURL& url, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| operation->RemoveDirectory( |
| url, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::CopyFileLocal( |
| const FileSystemURL& src_url, |
| const FileSystemURL& dest_url, |
| CopyOrMoveOption option, |
| const CopyFileProgressCallback& progress_callback, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(src_url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| operation->CopyFileLocal( |
| src_url, dest_url, option, progress_callback, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| OperationID FileSystemOperationRunner::MoveFileLocal( |
| const FileSystemURL& src_url, |
| const FileSystemURL& dest_url, |
| CopyOrMoveOption option, |
| const StatusCallback& callback) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| FileSystemOperation* operation = |
| file_system_context_->CreateFileSystemOperation(src_url, &error); |
| BeginOperationScoper scope; |
| OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); |
| if (!operation) { |
| DidFinish(handle, callback, error); |
| return handle.id; |
| } |
| operation->MoveFileLocal( |
| src_url, dest_url, option, |
| base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), |
| handle, callback)); |
| return handle.id; |
| } |
| |
| base::PlatformFileError FileSystemOperationRunner::SyncGetPlatformPath( |
| const FileSystemURL& url, |
| base::FilePath* platform_path) { |
| base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| scoped_ptr<FileSystemOperation> operation( |
| file_system_context_->CreateFileSystemOperation(url, &error)); |
| if (!operation.get()) |
| return error; |
| return operation->SyncGetPlatformPath(url, platform_path); |
| } |
| |
| FileSystemOperationRunner::FileSystemOperationRunner( |
| FileSystemContext* file_system_context) |
| : file_system_context_(file_system_context) {} |
| |
| void FileSystemOperationRunner::DidFinish( |
| const OperationHandle& handle, |
| const StatusCallback& callback, |
| base::PlatformFileError rv) { |
| if (handle.scope) { |
| finished_operations_.insert(handle.id); |
| base::MessageLoopProxy::current()->PostTask( |
| FROM_HERE, base::Bind(&FileSystemOperationRunner::DidFinish, |
| AsWeakPtr(), handle, callback, rv)); |
| return; |
| } |
| callback.Run(rv); |
| FinishOperation(handle.id); |
| } |
| |
| void FileSystemOperationRunner::DidGetMetadata( |
| const OperationHandle& handle, |
| const GetMetadataCallback& callback, |
| base::PlatformFileError rv, |
| const base::PlatformFileInfo& file_info) { |
| if (handle.scope) { |
| finished_operations_.insert(handle.id); |
| base::MessageLoopProxy::current()->PostTask( |
| FROM_HERE, base::Bind(&FileSystemOperationRunner::DidGetMetadata, |
| AsWeakPtr(), handle, callback, rv, file_info)); |
| return; |
| } |
| callback.Run(rv, file_info); |
| FinishOperation(handle.id); |
| } |
| |
| void FileSystemOperationRunner::DidReadDirectory( |
| const OperationHandle& handle, |
| const ReadDirectoryCallback& callback, |
| base::PlatformFileError rv, |
| const std::vector<DirectoryEntry>& entries, |
| bool has_more) { |
| if (handle.scope) { |
| finished_operations_.insert(handle.id); |
| base::MessageLoopProxy::current()->PostTask( |
| FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory, |
| AsWeakPtr(), handle, callback, rv, |
| entries, has_more)); |
| return; |
| } |
| callback.Run(rv, entries, has_more); |
| if (rv != base::PLATFORM_FILE_OK || !has_more) |
| FinishOperation(handle.id); |
| } |
| |
| void FileSystemOperationRunner::DidWrite( |
| const OperationHandle& handle, |
| const WriteCallback& callback, |
| base::PlatformFileError rv, |
| int64 bytes, |
| bool complete) { |
| if (handle.scope) { |
| finished_operations_.insert(handle.id); |
| base::MessageLoopProxy::current()->PostTask( |
| FROM_HERE, base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), |
| handle, callback, rv, bytes, complete)); |
| return; |
| } |
| callback.Run(rv, bytes, complete); |
| if (rv != base::PLATFORM_FILE_OK || complete) |
| FinishOperation(handle.id); |
| } |
| |
| void FileSystemOperationRunner::DidOpenFile( |
| const OperationHandle& handle, |
| const OpenFileCallback& callback, |
| base::PlatformFileError rv, |
| base::PlatformFile file, |
| const base::Closure& on_close_callback) { |
| if (handle.scope) { |
| finished_operations_.insert(handle.id); |
| base::MessageLoopProxy::current()->PostTask( |
| FROM_HERE, base::Bind(&FileSystemOperationRunner::DidOpenFile, |
| AsWeakPtr(), handle, callback, rv, file, |
| on_close_callback)); |
| return; |
| } |
| callback.Run(rv, file, on_close_callback); |
| FinishOperation(handle.id); |
| } |
| |
| void FileSystemOperationRunner::DidCreateSnapshot( |
| const OperationHandle& handle, |
| const SnapshotFileCallback& callback, |
| base::PlatformFileError rv, |
| const base::PlatformFileInfo& file_info, |
| const base::FilePath& platform_path, |
| const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { |
| if (handle.scope) { |
| finished_operations_.insert(handle.id); |
| base::MessageLoopProxy::current()->PostTask( |
| FROM_HERE, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, |
| AsWeakPtr(), handle, callback, rv, file_info, |
| platform_path, file_ref)); |
| return; |
| } |
| callback.Run(rv, file_info, platform_path, file_ref); |
| FinishOperation(handle.id); |
| } |
| |
| void FileSystemOperationRunner::OnCopyProgress( |
| const OperationHandle& handle, |
| const CopyProgressCallback& callback, |
| FileSystemOperation::CopyProgressType type, |
| const FileSystemURL& source_url, |
| const FileSystemURL& dest_url, |
| int64 size) { |
| if (handle.scope) { |
| base::MessageLoopProxy::current()->PostTask( |
| FROM_HERE, base::Bind( |
| &FileSystemOperationRunner::OnCopyProgress, |
| AsWeakPtr(), handle, callback, type, source_url, dest_url, size)); |
| return; |
| } |
| callback.Run(type, source_url, dest_url, size); |
| } |
| |
| void FileSystemOperationRunner::PrepareForWrite(OperationID id, |
| const FileSystemURL& url) { |
| if (file_system_context_->GetUpdateObservers(url.type())) { |
| file_system_context_->GetUpdateObservers(url.type())->Notify( |
| &FileUpdateObserver::OnStartUpdate, MakeTuple(url)); |
| } |
| write_target_urls_[id].insert(url); |
| } |
| |
| void FileSystemOperationRunner::PrepareForRead(OperationID id, |
| const FileSystemURL& url) { |
| if (file_system_context_->GetAccessObservers(url.type())) { |
| file_system_context_->GetAccessObservers(url.type())->Notify( |
| &FileAccessObserver::OnAccess, MakeTuple(url)); |
| } |
| } |
| |
| FileSystemOperationRunner::OperationHandle |
| FileSystemOperationRunner::BeginOperation( |
| FileSystemOperation* operation, |
| base::WeakPtr<BeginOperationScoper> scope) { |
| OperationHandle handle; |
| handle.id = operations_.Add(operation); |
| handle.scope = scope; |
| return handle; |
| } |
| |
| void FileSystemOperationRunner::FinishOperation(OperationID id) { |
| OperationToURLSet::iterator found = write_target_urls_.find(id); |
| if (found != write_target_urls_.end()) { |
| const FileSystemURLSet& urls = found->second; |
| for (FileSystemURLSet::const_iterator iter = urls.begin(); |
| iter != urls.end(); ++iter) { |
| if (file_system_context_->GetUpdateObservers(iter->type())) { |
| file_system_context_->GetUpdateObservers(iter->type())->Notify( |
| &FileUpdateObserver::OnEndUpdate, MakeTuple(*iter)); |
| } |
| } |
| write_target_urls_.erase(found); |
| } |
| |
| // IDMap::Lookup fails if the operation is NULL, so we don't check |
| // operations_.Lookup(id) here. |
| |
| operations_.Remove(id); |
| finished_operations_.erase(id); |
| |
| // Dispatch stray cancel callback if exists. |
| std::map<OperationID, StatusCallback>::iterator found_cancel = |
| stray_cancel_callbacks_.find(id); |
| if (found_cancel != stray_cancel_callbacks_.end()) { |
| // This cancel has been requested after the operation has finished, |
| // so report that we failed to stop it. |
| found_cancel->second.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); |
| stray_cancel_callbacks_.erase(found_cancel); |
| } |
| } |
| |
| } // namespace fileapi |