Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(743)

Unified Diff: webkit/browser/fileapi/copy_or_move_operation_delegate.cc

Issue 23621026: Extract CopyOrMoveFile operation into classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webkit/browser/fileapi/copy_or_move_operation_delegate.cc
diff --git a/webkit/browser/fileapi/copy_or_move_operation_delegate.cc b/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
index 844234ffa5388b7571c0c48d4ef2c655a6430e0c..149904ca3911c8c413e2e185a92d2ae45866b667 100644
--- a/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
+++ b/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
@@ -16,6 +16,264 @@
namespace fileapi {
+// Needs to define the interface in before the each implementation define below.
kinuko 2013/09/09 16:12:38 nit: ditto, this comment's probably not necessary
hidehiko 2013/09/09 16:55:35 Removed.
+class CopyOrMoveOperationDelegate::CopyOrMoveImpl {
+ public:
+ virtual ~CopyOrMoveImpl() {}
+ virtual void Run(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback) = 0;
+ protected:
+ CopyOrMoveImpl() {}
+ DISALLOW_COPY_AND_ASSIGN(CopyOrMoveImpl);
+};
+
+namespace {
+
+// Copies a file on a (same) file system. Just delegate the operation to
+// |operation_runner|.
+class CopyOrMoveOnSameFileSystemImpl
+ : public CopyOrMoveOperationDelegate::CopyOrMoveImpl {
+ public:
+ CopyOrMoveOnSameFileSystemImpl(
+ FileSystemOperationRunner* operation_runner,
+ CopyOrMoveOperationDelegate::OperationType operation_type,
+ const FileSystemURL& src_url,
+ const FileSystemURL& dest_url)
+ : operation_runner_(operation_runner),
+ operation_type_(operation_type),
+ src_url_(src_url),
+ dest_url_(dest_url) {
+ }
+
+ virtual void Run(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE {
+ if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_MOVE) {
+ operation_runner_->MoveFileLocal(src_url_, dest_url_, callback);
+ } else {
+ // TODO(hidehiko): Support progress callback.
+ operation_runner_->CopyFileLocal(
+ src_url_, dest_url_,
+ FileSystemOperationRunner::CopyFileProgressCallback(), callback);
+ }
+ }
+
+ private:
+ FileSystemOperationRunner* operation_runner_;
+ CopyOrMoveOperationDelegate::OperationType operation_type_;
+ FileSystemURL src_url_;
+ FileSystemURL dest_url_;
+ DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOnSameFileSystemImpl);
+};
+
+// Espacially for cross file system copy/move operation, this class creates
kinuko 2013/09/09 16:12:38 nit: Especially -> Specifically ? (Since it's spe
hidehiko 2013/09/09 16:55:35 Done.
+// a snapshot file, validate it if necessary, run copying process,
+// validate the created file, and remove source file for move (noop for copy).
kinuko 2013/09/09 16:12:38 nit: validate -> validates, run -> runs, remove ->
hidehiko 2013/09/09 16:55:35 Done.
+class SnapshotCopyOrMoveImpl
+ : public CopyOrMoveOperationDelegate::CopyOrMoveImpl {
+ public:
+ SnapshotCopyOrMoveImpl(
+ FileSystemOperationRunner* operation_runner,
+ CopyOrMoveOperationDelegate::OperationType operation_type,
+ const FileSystemURL& src_url,
+ const FileSystemURL& dest_url,
kinuko 2013/09/09 16:12:38 nit: extra space
hidehiko 2013/09/09 16:55:35 Oops done.
+ CopyOrMoveFileValidatorFactory* validator_factory)
+ : operation_runner_(operation_runner),
+ operation_type_(operation_type),
+ src_url_(src_url),
+ dest_url_(dest_url),
+ validator_factory_(validator_factory),
+ weak_factory_(this) {
+ }
+
+ virtual void Run(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE {
+ operation_runner_->CreateSnapshotFile(
+ src_url_,
+ base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCreateSnapshot,
+ weak_factory_.GetWeakPtr(), callback));
+ }
+
+ private:
+ void RunAfterCreateSnapshot(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error,
+ const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path,
+ const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
+ if (error != base::PLATFORM_FILE_OK) {
+ callback.Run(error);
+ return;
+ }
+
+ // For now we assume CreateSnapshotFile always return a valid local file
+ // path.
+ // TODO(kinuko): Otherwise create a FileStreamReader to perform a copy/move.
kinuko 2013/09/09 16:12:38 nit: maybe we can remove this comment now?
hidehiko 2013/09/09 16:55:35 Done.
+ DCHECK(!platform_path.empty());
+
+ if (!validator_factory_) {
+ // No validation is needed.
+ RunAfterPreWriteValidation(
+ platform_path, file_ref, callback, base::PLATFORM_FILE_OK);
+ return;
+ }
+
+ // Runs pre write validation.
kinuko 2013/09/09 16:12:38 nit: Runs -> Run
hidehiko 2013/09/09 16:55:35 Done.
+ PreWriteValidation(
+ platform_path,
+ base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPreWriteValidation,
+ weak_factory_.GetWeakPtr(),
+ platform_path, file_ref, callback));
+ }
+
+ void RunAfterPreWriteValidation(
+ const base::FilePath& platform_path,
+ const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error) {
+ if (error != base::PLATFORM_FILE_OK) {
+ callback.Run(error);
+ return;
+ }
+
+ // |file_ref| is unused but necessary to keep the file alive until
+ // CopyInForeignFile() is completed.
+ operation_runner_->CopyInForeignFile(
+ platform_path, dest_url_,
+ base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCopyInForeignFile,
+ weak_factory_.GetWeakPtr(), file_ref, callback));
+ }
+
+ void RunAfterCopyInForeignFile(
+ const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error) {
+ if (error != base::PLATFORM_FILE_OK) {
+ callback.Run(error);
+ return;
+ }
+
+ // |validator_| is NULL in when the destination filesystem does not do
kinuko 2013/09/09 16:12:38 nit: 'in when' -> when
hidehiko 2013/09/09 16:55:35 Done.
+ // validation.
+ if (!validator_) {
+ // No validation is needed.
+ RunAfterPostWriteValidation(callback, base::PLATFORM_FILE_OK);
+ return;
+ }
+
+ PostWriteValidation(
+ base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPostWriteValidation,
+ weak_factory_.GetWeakPtr(), callback));
+ }
+
+ void RunAfterPostWriteValidation(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error) {
+ if (error != base::PLATFORM_FILE_OK) {
+ // Failed to validate. Remove the destination file.
+ operation_runner_->Remove(
+ dest_url_, true,
kinuko 2013/09/09 16:12:38 nit: can you add /* recursive */ after true while
hidehiko 2013/09/09 16:55:35 Done.
+ base::Bind(&SnapshotCopyOrMoveImpl::DidRemoveDestForError,
+ weak_factory_.GetWeakPtr(), error, callback));
+ return;
+ }
+
+ if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) {
+ callback.Run(base::PLATFORM_FILE_OK);
+ return;
+ }
+
+ DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_);
+
+ // Remove the source for finalizing move operation.
+ operation_runner_->Remove(
+ src_url_, true /* recursive */,
+ base::Bind(&SnapshotCopyOrMoveImpl::RunAfterRemoveSourceForMove,
+ weak_factory_.GetWeakPtr(), callback));
+ }
+
+ void RunAfterRemoveSourceForMove(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error) {
+ if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
+ error = base::PLATFORM_FILE_OK;
+ callback.Run(error);
+ }
+
+ void DidRemoveDestForError(
+ base::PlatformFileError prior_error,
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error) {
+ if (error != base::PLATFORM_FILE_OK) {
+ VLOG(1) << "Error removing destination file after validation error: "
+ << error;
+ }
+ callback.Run(prior_error);
+ }
+
+ // Runs pre-write validation.
+ void PreWriteValidation(
+ const base::FilePath& platform_path,
+ const CopyOrMoveOperationDelegate::StatusCallback& callback) {
+ DCHECK(validator_factory_);
+ validator_.reset(
+ validator_factory_->CreateCopyOrMoveFileValidator(
+ src_url_, platform_path));
+ validator_->StartPreWriteValidation(callback);
+ }
+
+ // Runs post-write validation.
+ void PostWriteValidation(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback) {
+ operation_runner_->CreateSnapshotFile(
+ dest_url_,
+ base::Bind(
+ &SnapshotCopyOrMoveImpl::PostWriteValidationAfterCreateSnapshotFile,
+ weak_factory_.GetWeakPtr(), callback));
+ }
+
+ void PostWriteValidationAfterCreateSnapshotFile(
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error,
+ const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path,
+ const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
+ if (error != base::PLATFORM_FILE_OK) {
+ callback.Run(error);
+ return;
+ }
+
+ DCHECK(validator_);
+ // Note: file_ref passed here to keep the file alive until after
+ // the StartPostWriteValidation operation finishes.
+ validator_->StartPostWriteValidation(
+ platform_path,
+ base::Bind(&SnapshotCopyOrMoveImpl::DidPostWriteValidation,
+ weak_factory_.GetWeakPtr(), file_ref, callback));
+ }
+
+ // |file_ref| is unused; it is passed here to make sure the reference is
+ // alive until after post-write validation is complete.
+ void DidPostWriteValidation(
+ const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
+ const CopyOrMoveOperationDelegate::StatusCallback& callback,
+ base::PlatformFileError error) {
+ callback.Run(error);
+ }
+
+ FileSystemOperationRunner* operation_runner_;
+ CopyOrMoveOperationDelegate::OperationType operation_type_;
+ FileSystemURL src_url_;
+ FileSystemURL dest_url_;
+ CopyOrMoveFileValidatorFactory* validator_factory_;
+ scoped_ptr<CopyOrMoveFileValidator> validator_;
+
+ base::WeakPtrFactory<SnapshotCopyOrMoveImpl> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(SnapshotCopyOrMoveImpl);
+};
+
+} // namespace
+
+
CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate(
FileSystemContext* file_system_context,
const FileSystemURL& src_root,
@@ -32,6 +290,7 @@ CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate(
}
CopyOrMoveOperationDelegate::~CopyOrMoveOperationDelegate() {
+ STLDeleteElements(&running_copy_set_);
}
void CopyOrMoveOperationDelegate::Run() {
@@ -55,14 +314,14 @@ void CopyOrMoveOperationDelegate::RunRecursively() {
}
// First try to copy/move it as a file.
- CopyOrMoveFile(URLPair(src_root_, dest_root_),
+ CopyOrMoveFile(src_root_, dest_root_,
base::Bind(&CopyOrMoveOperationDelegate::DidTryCopyOrMoveFile,
weak_factory_.GetWeakPtr()));
}
void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url,
const StatusCallback& callback) {
- CopyOrMoveFile(URLPair(src_url, CreateDestURL(src_url)), callback);
+ CopyOrMoveFile(src_url, CreateDestURL(src_url), callback);
}
void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url,
@@ -116,85 +375,6 @@ void CopyOrMoveOperationDelegate::DidTryRemoveDestRoot(
weak_factory_.GetWeakPtr(), src_root_, callback_));
}
-void CopyOrMoveOperationDelegate::CopyOrMoveFile(
- const URLPair& url_pair,
- const StatusCallback& callback) {
- // Same filesystem case.
- if (same_file_system_) {
- if (operation_type_ == OPERATION_MOVE) {
- operation_runner()->MoveFileLocal(url_pair.src, url_pair.dest, callback);
- } else {
- // TODO(hidehiko): Support progress callback.
- operation_runner()->CopyFileLocal(
- url_pair.src, url_pair.dest,
- FileSystemOperationRunner::CopyFileProgressCallback(), callback);
- }
- return;
- }
-
- // Cross filesystem case.
- // Perform CreateSnapshotFile, CopyInForeignFile and then calls
- // copy_callback which removes the source file if operation_type == MOVE.
- StatusCallback copy_callback =
- base::Bind(&CopyOrMoveOperationDelegate::DidFinishCopy,
- weak_factory_.GetWeakPtr(), url_pair, callback);
- operation_runner()->CreateSnapshotFile(
- url_pair.src,
- base::Bind(&CopyOrMoveOperationDelegate::DidCreateSnapshot,
- weak_factory_.GetWeakPtr(), url_pair, copy_callback));
-}
-
-void CopyOrMoveOperationDelegate::DidCreateSnapshot(
- const URLPair& url_pair,
- const StatusCallback& callback,
- base::PlatformFileError error,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
- if (error != base::PLATFORM_FILE_OK) {
- callback.Run(error);
- return;
- }
- current_file_ref_ = file_ref;
-
- // For now we assume CreateSnapshotFile always return a valid local file path.
- // TODO(kinuko): Otherwise create a FileStreamReader to perform a copy/move.
- DCHECK(!platform_path.empty());
-
- CopyOrMoveFileValidatorFactory* factory =
- file_system_context()->GetCopyOrMoveFileValidatorFactory(
- dest_root_.type(), &error);
- if (error != base::PLATFORM_FILE_OK) {
- callback.Run(error);
- return;
- }
- if (!factory) {
- DidValidateFile(url_pair.dest, callback, file_info, platform_path, error);
- return;
- }
-
- validator_.reset(
- factory->CreateCopyOrMoveFileValidator(url_pair.src, platform_path));
- validator_->StartPreWriteValidation(
- base::Bind(&CopyOrMoveOperationDelegate::DidValidateFile,
- weak_factory_.GetWeakPtr(),
- url_pair.dest, callback, file_info, platform_path));
-}
-
-void CopyOrMoveOperationDelegate::DidValidateFile(
- const FileSystemURL& dest,
- const StatusCallback& callback,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path,
- base::PlatformFileError error) {
- if (error != base::PLATFORM_FILE_OK) {
- callback.Run(error);
- return;
- }
-
- operation_runner()->CopyInForeignFile(platform_path, dest, callback);
-}
-
void CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir(
const FileSystemURL& src,
const StatusCallback& callback,
@@ -214,89 +394,51 @@ void CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir(
weak_factory_.GetWeakPtr(), callback));
}
-void CopyOrMoveOperationDelegate::DidFinishCopy(
- const URLPair& url_pair,
+void CopyOrMoveOperationDelegate::DidRemoveSourceForMove(
const StatusCallback& callback,
base::PlatformFileError error) {
- if (error != base::PLATFORM_FILE_OK) {
- callback.Run(error);
- return;
- }
-
- // |validator_| is NULL in the same-filesystem case or when the destination
- // filesystem does not do validation.
- if (!validator_.get()) {
- scoped_refptr<webkit_blob::ShareableFileReference> file_ref;
- DidPostWriteValidation(url_pair, callback, file_ref,
- base::PLATFORM_FILE_OK);
- return;
- }
-
- DCHECK(!same_file_system_);
- operation_runner()->CreateSnapshotFile(
- url_pair.dest,
- base::Bind(&CopyOrMoveOperationDelegate::DoPostWriteValidation,
- weak_factory_.GetWeakPtr(), url_pair, callback));
+ if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
+ error = base::PLATFORM_FILE_OK;
+ callback.Run(error);
}
-void CopyOrMoveOperationDelegate::DoPostWriteValidation(
- const URLPair& url_pair,
- const StatusCallback& callback,
- base::PlatformFileError error,
- const base::PlatformFileInfo& file_info,
- const base::FilePath& platform_path,
- const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
- if (error != base::PLATFORM_FILE_OK) {
- operation_runner()->Remove(
- url_pair.dest, true,
- base::Bind(&CopyOrMoveOperationDelegate::DidRemoveDestForError,
- weak_factory_.GetWeakPtr(), error, callback));
- return;
- }
-
- DCHECK(validator_.get());
- // Note: file_ref passed here to keep the file alive until after
- // the StartPostWriteValidation operation finishes.
- validator_->StartPostWriteValidation(
- platform_path,
- base::Bind(&CopyOrMoveOperationDelegate::DidPostWriteValidation,
- weak_factory_.GetWeakPtr(), url_pair, callback, file_ref));
-}
+void CopyOrMoveOperationDelegate::CopyOrMoveFile(
+ const FileSystemURL& src_url,
+ const FileSystemURL& dest_url,
+ const StatusCallback& callback) {
+ CopyOrMoveImpl* impl = NULL;
+ if (same_file_system_) {
+ impl = new CopyOrMoveOnSameFileSystemImpl(
+ operation_runner(), operation_type_, src_url, dest_url);
+ } else {
+ // Cross filesystem case.
+ // TODO(hidehiko): Support stream based copy. crbug.com/279287.
+ base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
+ CopyOrMoveFileValidatorFactory* validator_factory =
+ file_system_context()->GetCopyOrMoveFileValidatorFactory(
+ dest_root_.type(), &error);
+ if (error != base::PLATFORM_FILE_OK) {
+ callback.Run(error);
+ return;
+ }
-// |file_ref| is unused; it is passed here to make sure the reference is
-// alive until after post-write validation is complete.
-void CopyOrMoveOperationDelegate::DidPostWriteValidation(
- const URLPair& url_pair,
- const StatusCallback& callback,
- const scoped_refptr<webkit_blob::ShareableFileReference>& /*file_ref*/,
- base::PlatformFileError error) {
- if (error != base::PLATFORM_FILE_OK) {
- operation_runner()->Remove(
- url_pair.dest, true,
- base::Bind(&CopyOrMoveOperationDelegate::DidRemoveDestForError,
- weak_factory_.GetWeakPtr(), error, callback));
- return;
+ impl = new SnapshotCopyOrMoveImpl(
+ operation_runner(), operation_type_, src_url, dest_url,
+ validator_factory);
}
- if (operation_type_ == OPERATION_COPY) {
- callback.Run(error);
- return;
- }
-
- DCHECK_EQ(OPERATION_MOVE, operation_type_);
-
- // Remove the source for finalizing move operation.
- operation_runner()->Remove(
- url_pair.src, true /* recursive */,
- base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove,
- weak_factory_.GetWeakPtr(), callback));
+ // Register the running task.
+ running_copy_set_.insert(impl);
+ impl->Run(base::Bind(&CopyOrMoveOperationDelegate::DidCopyOrMoveFile,
+ weak_factory_.GetWeakPtr(), impl, callback));
}
-void CopyOrMoveOperationDelegate::DidRemoveSourceForMove(
+void CopyOrMoveOperationDelegate::DidCopyOrMoveFile(
+ CopyOrMoveImpl* impl,
const StatusCallback& callback,
base::PlatformFileError error) {
- if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
- error = base::PLATFORM_FILE_OK;
+ running_copy_set_.erase(impl);
+ delete impl;
callback.Run(error);
}
@@ -314,15 +456,4 @@ FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL(
relative);
}
-void CopyOrMoveOperationDelegate::DidRemoveDestForError(
- base::PlatformFileError prior_error,
- const StatusCallback& callback,
- base::PlatformFileError error) {
- if (error != base::PLATFORM_FILE_OK) {
- VLOG(1) << "Error removing destination file after validation error: "
- << error;
- }
- callback.Run(prior_error);
-}
-
} // namespace fileapi

Powered by Google App Engine
This is Rietveld 408576698