summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorhidehiko@chromium.org <hidehiko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-12 13:07:42 +0000
committerhidehiko@chromium.org <hidehiko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-12 13:07:42 +0000
commitb2ef40c775cba50c908f1b72d377a19b8c457b36 (patch)
treeed74257b5534b026a220106a5063a70c363a49d3 /webkit
parentcf90f2e21739d39319d9f04cde8ceb4cefc0fb6c (diff)
downloadchromium_src-b2ef40c775cba50c908f1b72d377a19b8c457b36.zip
chromium_src-b2ef40c775cba50c908f1b72d377a19b8c457b36.tar.gz
chromium_src-b2ef40c775cba50c908f1b72d377a19b8c457b36.tar.bz2
Implement CopyProgressCallback on CopyOrMoveOperationDelegate.
By this CL, FileSystemOperationRunner::Copy starts to support progress callback. BUG=278038 TEST=Ran content_unittests Review URL: https://chromiumcodereview.appspot.com/23558011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222770 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/browser/fileapi/async_file_test_helper.cc10
-rw-r--r--webkit/browser/fileapi/async_file_test_helper.h8
-rw-r--r--webkit/browser/fileapi/copy_or_move_operation_delegate.cc97
-rw-r--r--webkit/browser/fileapi/copy_or_move_operation_delegate.h8
-rw-r--r--webkit/browser/fileapi/copy_or_move_operation_delegate_unittest.cc98
-rw-r--r--webkit/browser/fileapi/file_system_operation_impl.cc3
-rw-r--r--webkit/browser/fileapi/file_system_url.h4
7 files changed, 205 insertions, 23 deletions
diff --git a/webkit/browser/fileapi/async_file_test_helper.cc b/webkit/browser/fileapi/async_file_test_helper.cc
index eaf8441..a6dab38 100644
--- a/webkit/browser/fileapi/async_file_test_helper.cc
+++ b/webkit/browser/fileapi/async_file_test_helper.cc
@@ -94,10 +94,18 @@ base::PlatformFileError AsyncFileTestHelper::Copy(
FileSystemContext* context,
const FileSystemURL& src,
const FileSystemURL& dest) {
+ return CopyWithProgress(context, src, dest, CopyProgressCallback());
+}
+
+base::PlatformFileError AsyncFileTestHelper::CopyWithProgress(
+ FileSystemContext* context,
+ const FileSystemURL& src,
+ const FileSystemURL& dest,
+ const CopyProgressCallback& progress_callback) {
base::PlatformFileError result = base::PLATFORM_FILE_ERROR_FAILED;
base::RunLoop run_loop;
context->operation_runner()->Copy(
- src, dest, FileSystemOperationRunner::CopyProgressCallback(),
+ src, dest, progress_callback,
AssignAndQuitCallback(&run_loop, &result));
run_loop.Run();
return result;
diff --git a/webkit/browser/fileapi/async_file_test_helper.h b/webkit/browser/fileapi/async_file_test_helper.h
index da27bf2..168400f 100644
--- a/webkit/browser/fileapi/async_file_test_helper.h
+++ b/webkit/browser/fileapi/async_file_test_helper.h
@@ -23,6 +23,7 @@ class FileSystemURL;
class AsyncFileTestHelper {
public:
typedef FileSystemOperation::FileEntryList FileEntryList;
+ typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback;
static const int64 kDontCheckSize;
@@ -31,6 +32,13 @@ class AsyncFileTestHelper {
const FileSystemURL& src,
const FileSystemURL& dest);
+ // Same as Copy, but this supports |progress_callback|.
+ static base::PlatformFileError CopyWithProgress(
+ FileSystemContext* context,
+ const FileSystemURL& src,
+ const FileSystemURL& dest,
+ const CopyProgressCallback& progress_callback);
+
// Performs Move from |src| to |dest| and returns the status code.
static base::PlatformFileError Move(FileSystemContext* context,
const FileSystemURL& src,
diff --git a/webkit/browser/fileapi/copy_or_move_operation_delegate.cc b/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
index 37e9a93..7634a88 100644
--- a/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
+++ b/webkit/browser/fileapi/copy_or_move_operation_delegate.cc
@@ -37,11 +37,14 @@ class CopyOrMoveOnSameFileSystemImpl
FileSystemOperationRunner* operation_runner,
CopyOrMoveOperationDelegate::OperationType operation_type,
const FileSystemURL& src_url,
- const FileSystemURL& dest_url)
+ const FileSystemURL& dest_url,
+ const FileSystemOperation::CopyFileProgressCallback&
+ file_progress_callback)
: operation_runner_(operation_runner),
operation_type_(operation_type),
src_url_(src_url),
- dest_url_(dest_url) {
+ dest_url_(dest_url),
+ file_progress_callback_(file_progress_callback) {
}
virtual void Run(
@@ -49,10 +52,8 @@ class CopyOrMoveOnSameFileSystemImpl
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);
+ src_url_, dest_url_, file_progress_callback_, callback);
}
}
@@ -61,6 +62,7 @@ class CopyOrMoveOnSameFileSystemImpl
CopyOrMoveOperationDelegate::OperationType operation_type_;
FileSystemURL src_url_;
FileSystemURL dest_url_;
+ FileSystemOperation::CopyFileProgressCallback file_progress_callback_;
DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOnSameFileSystemImpl);
};
@@ -76,17 +78,21 @@ class SnapshotCopyOrMoveImpl
CopyOrMoveOperationDelegate::OperationType operation_type,
const FileSystemURL& src_url,
const FileSystemURL& dest_url,
- CopyOrMoveFileValidatorFactory* validator_factory)
+ CopyOrMoveFileValidatorFactory* validator_factory,
+ const FileSystemOperation::CopyFileProgressCallback&
+ file_progress_callback)
: operation_runner_(operation_runner),
operation_type_(operation_type),
src_url_(src_url),
dest_url_(dest_url),
validator_factory_(validator_factory),
+ file_progress_callback_(file_progress_callback),
weak_factory_(this) {
}
virtual void Run(
const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE {
+ file_progress_callback_.Run(0);
operation_runner_->CreateSnapshotFile(
src_url_,
base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCreateSnapshot,
@@ -111,8 +117,8 @@ class SnapshotCopyOrMoveImpl
if (!validator_factory_) {
// No validation is needed.
- RunAfterPreWriteValidation(
- platform_path, file_ref, callback, base::PLATFORM_FILE_OK);
+ RunAfterPreWriteValidation(platform_path, file_info, file_ref, callback,
+ base::PLATFORM_FILE_OK);
return;
}
@@ -121,11 +127,12 @@ class SnapshotCopyOrMoveImpl
platform_path,
base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPreWriteValidation,
weak_factory_.GetWeakPtr(),
- platform_path, file_ref, callback));
+ platform_path, file_info, file_ref, callback));
}
void RunAfterPreWriteValidation(
const base::FilePath& platform_path,
+ const base::PlatformFileInfo& file_info,
const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
const CopyOrMoveOperationDelegate::StatusCallback& callback,
base::PlatformFileError error) {
@@ -139,10 +146,11 @@ class SnapshotCopyOrMoveImpl
operation_runner_->CopyInForeignFile(
platform_path, dest_url_,
base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCopyInForeignFile,
- weak_factory_.GetWeakPtr(), file_ref, callback));
+ weak_factory_.GetWeakPtr(), file_info, file_ref, callback));
}
void RunAfterCopyInForeignFile(
+ const base::PlatformFileInfo& file_info,
const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
const CopyOrMoveOperationDelegate::StatusCallback& callback,
base::PlatformFileError error) {
@@ -151,6 +159,8 @@ class SnapshotCopyOrMoveImpl
return;
}
+ file_progress_callback_.Run(file_info.size);
+
// |validator_| is NULL when the destination filesystem does not do
// validation.
if (!validator_) {
@@ -265,6 +275,7 @@ class SnapshotCopyOrMoveImpl
FileSystemURL dest_url_;
CopyOrMoveFileValidatorFactory* validator_factory_;
scoped_ptr<CopyOrMoveFileValidator> validator_;
+ FileSystemOperation::CopyFileProgressCallback file_progress_callback_;
base::WeakPtrFactory<SnapshotCopyOrMoveImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SnapshotCopyOrMoveImpl);
@@ -278,11 +289,13 @@ CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate(
const FileSystemURL& src_root,
const FileSystemURL& dest_root,
OperationType operation_type,
+ const CopyProgressCallback& progress_callback,
const StatusCallback& callback)
: RecursiveOperationDelegate(file_system_context),
src_root_(src_root),
dest_root_(dest_root),
operation_type_(operation_type),
+ progress_callback_(progress_callback),
callback_(callback),
weak_factory_(this) {
same_file_system_ = src_root_.IsInSameFileSystem(dest_root_);
@@ -312,33 +325,57 @@ void CopyOrMoveOperationDelegate::RunRecursively() {
return;
}
+ if (!progress_callback_.is_null()) {
+ progress_callback_.Run(
+ FileSystemOperation::BEGIN_COPY_ENTRY, src_root_, 0);
+ }
+
// First try to copy/move it as a file.
CopyOrMoveFile(src_root_, dest_root_,
base::Bind(&CopyOrMoveOperationDelegate::DidTryCopyOrMoveFile,
weak_factory_.GetWeakPtr()));
}
-void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url,
- const StatusCallback& callback) {
- CopyOrMoveFile(src_url, CreateDestURL(src_url), callback);
+void CopyOrMoveOperationDelegate::ProcessFile(
+ const FileSystemURL& src_url,
+ const StatusCallback& callback) {
+ if (!progress_callback_.is_null())
+ progress_callback_.Run(FileSystemOperation::BEGIN_COPY_ENTRY, src_url, 0);
+
+ CopyOrMoveFile(src_url, CreateDestURL(src_url),
+ base::Bind(&CopyOrMoveOperationDelegate::DidCopyEntry,
+ weak_factory_.GetWeakPtr(), src_url, callback));
}
-void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url,
- const StatusCallback& callback) {
+void CopyOrMoveOperationDelegate::ProcessDirectory(
+ const FileSystemURL& src_url,
+ const StatusCallback& callback) {
FileSystemURL dest_url = CreateDestURL(src_url);
+ if (!progress_callback_.is_null() && src_url != src_root_) {
+ // We do not invoke |progress_callback_| for source root, because it is
+ // already called in RunRecursively().
+ progress_callback_.Run(FileSystemOperation::BEGIN_COPY_ENTRY, src_url, 0);
+ }
+
// If operation_type == Move we may need to record directories and
// restore directory timestamps in the end, though it may have
// negative performance impact.
// See http://crbug.com/171284 for more details.
operation_runner()->CreateDirectory(
- dest_url, false /* exclusive */, false /* recursive */, callback);
+ dest_url, false /* exclusive */, false /* recursive */,
+ base::Bind(&CopyOrMoveOperationDelegate::DidCopyEntry,
+ weak_factory_.GetWeakPtr(), src_url, callback));
}
void CopyOrMoveOperationDelegate::DidTryCopyOrMoveFile(
base::PlatformFileError error) {
- if (error == base::PLATFORM_FILE_OK ||
- error != base::PLATFORM_FILE_ERROR_NOT_A_FILE) {
+ if (error != base::PLATFORM_FILE_ERROR_NOT_A_FILE) {
+ if (error == base::PLATFORM_FILE_OK && !progress_callback_.is_null()) {
+ progress_callback_.Run(
+ FileSystemOperation::END_COPY_ENTRY, src_root_, 0);
+ }
+
callback_.Run(error);
return;
}
@@ -408,7 +445,9 @@ void CopyOrMoveOperationDelegate::CopyOrMoveFile(
CopyOrMoveImpl* impl = NULL;
if (same_file_system_) {
impl = new CopyOrMoveOnSameFileSystemImpl(
- operation_runner(), operation_type_, src_url, dest_url);
+ operation_runner(), operation_type_, src_url, dest_url,
+ base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress,
+ weak_factory_.GetWeakPtr(), src_url));
} else {
// Cross filesystem case.
// TODO(hidehiko): Support stream based copy. crbug.com/279287.
@@ -423,7 +462,9 @@ void CopyOrMoveOperationDelegate::CopyOrMoveFile(
impl = new SnapshotCopyOrMoveImpl(
operation_runner(), operation_type_, src_url, dest_url,
- validator_factory);
+ validator_factory,
+ base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress,
+ weak_factory_.GetWeakPtr(), src_url));
}
// Register the running task.
@@ -432,6 +473,16 @@ void CopyOrMoveOperationDelegate::CopyOrMoveFile(
weak_factory_.GetWeakPtr(), impl, callback));
}
+void CopyOrMoveOperationDelegate::DidCopyEntry(
+ const FileSystemURL& src_url,
+ const StatusCallback& callback,
+ base::PlatformFileError error) {
+ if (!progress_callback_.is_null() && error == base::PLATFORM_FILE_OK)
+ progress_callback_.Run(FileSystemOperation::END_COPY_ENTRY, src_url, 0);
+
+ callback.Run(error);
+}
+
void CopyOrMoveOperationDelegate::DidCopyOrMoveFile(
CopyOrMoveImpl* impl,
const StatusCallback& callback,
@@ -441,6 +492,12 @@ void CopyOrMoveOperationDelegate::DidCopyOrMoveFile(
callback.Run(error);
}
+void CopyOrMoveOperationDelegate::OnCopyFileProgress(
+ const FileSystemURL& src_url, int64 size) {
+ if (!progress_callback_.is_null())
+ progress_callback_.Run(FileSystemOperation::PROGRESS, src_url, size);
+}
+
FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL(
const FileSystemURL& src_url) const {
DCHECK_EQ(src_root_.type(), src_url.type());
diff --git a/webkit/browser/fileapi/copy_or_move_operation_delegate.h b/webkit/browser/fileapi/copy_or_move_operation_delegate.h
index 5f629ca..cb409ce 100644
--- a/webkit/browser/fileapi/copy_or_move_operation_delegate.h
+++ b/webkit/browser/fileapi/copy_or_move_operation_delegate.h
@@ -24,6 +24,7 @@ class CopyOrMoveOperationDelegate
: public RecursiveOperationDelegate {
public:
class CopyOrMoveImpl;
+ typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback;
enum OperationType {
OPERATION_COPY,
@@ -35,6 +36,7 @@ class CopyOrMoveOperationDelegate
const FileSystemURL& src_root,
const FileSystemURL& dest_root,
OperationType operation_type,
+ const CopyProgressCallback& progress_callback,
const StatusCallback& callback);
virtual ~CopyOrMoveOperationDelegate();
@@ -55,6 +57,11 @@ class CopyOrMoveOperationDelegate
void DidRemoveSourceForMove(const StatusCallback& callback,
base::PlatformFileError error);
+ void DidCopyEntry(const FileSystemURL& src_url,
+ const StatusCallback& callback,
+ base::PlatformFileError error);
+ void OnCopyFileProgress(const FileSystemURL& src_url, int64 size);
+
// Starts Copy (or Move based on |operation_type_|) from |src_url| to
// |dest_url|. Upon completion |callback| is invoked.
// This can be run for multiple files in parallel.
@@ -71,6 +78,7 @@ class CopyOrMoveOperationDelegate
FileSystemURL dest_root_;
bool same_file_system_;
OperationType operation_type_;
+ CopyProgressCallback progress_callback_;
StatusCallback callback_;
std::set<CopyOrMoveImpl*> running_copy_set_;
diff --git a/webkit/browser/fileapi/copy_or_move_operation_delegate_unittest.cc b/webkit/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
index 183becd..fa2314d 100644
--- a/webkit/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
+++ b/webkit/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
@@ -93,6 +93,24 @@ class TestValidatorFactory : public CopyOrMoveFileValidatorFactory {
};
};
+// Records CopyProgressCallback invocations.
+struct ProgressRecord {
+ FileSystemOperation::CopyProgressType type;
+ FileSystemURL url;
+ int64 size;
+};
+
+void RecordProgressCallback(std::vector<ProgressRecord>* records,
+ FileSystemOperation::CopyProgressType type,
+ const FileSystemURL& url,
+ int64 size) {
+ ProgressRecord record;
+ record.type = type;
+ record.url = url;
+ record.size = size;
+ records->push_back(record);
+}
+
} // namespace
class CopyOrMoveOperationTestHelper {
@@ -194,6 +212,14 @@ class CopyOrMoveOperationTestHelper {
return AsyncFileTestHelper::Copy(file_system_context_.get(), src, dest);
}
+ base::PlatformFileError CopyWithProgress(
+ const FileSystemURL& src,
+ const FileSystemURL& dest,
+ const AsyncFileTestHelper::CopyProgressCallback& progress_callback) {
+ return AsyncFileTestHelper::CopyWithProgress(
+ file_system_context_.get(), src, dest, progress_callback);
+ }
+
base::PlatformFileError Move(const FileSystemURL& src,
const FileSystemURL& dest) {
return AsyncFileTestHelper::Move(file_system_context_.get(), src, dest);
@@ -453,7 +479,10 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopyDirectory) {
int64 src_increase = helper.GetSourceUsage() - src_initial_usage;
// Copy it.
- ASSERT_EQ(base::PLATFORM_FILE_OK, helper.Copy(src, dest));
+ ASSERT_EQ(base::PLATFORM_FILE_OK,
+ helper.CopyWithProgress(
+ src, dest,
+ AsyncFileTestHelper::CopyProgressCallback()));
// Verify.
ASSERT_TRUE(helper.DirectoryExists(src));
@@ -559,4 +588,71 @@ TEST(LocalFileSystemCopyOrMoveOperationTest, CopySingleFileNoValidator) {
ASSERT_EQ(base::PLATFORM_FILE_ERROR_SECURITY, helper.Copy(src, dest));
}
+TEST(LocalFileSystemCopyOrMoveOperationTest, ProgressCallback) {
+ CopyOrMoveOperationTestHelper helper(GURL("http://foo"),
+ kFileSystemTypeTemporary,
+ kFileSystemTypePersistent);
+ helper.SetUp();
+
+ FileSystemURL src = helper.SourceURL("a");
+ FileSystemURL dest = helper.DestURL("b");
+
+ // Set up a source directory.
+ ASSERT_EQ(base::PLATFORM_FILE_OK, helper.CreateDirectory(src));
+ ASSERT_EQ(base::PLATFORM_FILE_OK,
+ helper.SetUpTestCaseFiles(src,
+ test::kRegularTestCases,
+ test::kRegularTestCaseSize));
+
+ std::vector<ProgressRecord> records;
+ ASSERT_EQ(base::PLATFORM_FILE_OK,
+ helper.CopyWithProgress(src, dest,
+ base::Bind(&RecordProgressCallback,
+ base::Unretained(&records))));
+
+ // Verify progress callback.
+ for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) {
+ const test::TestCaseRecord& test_case = test::kRegularTestCases[i];
+
+ FileSystemURL src_url =
+ helper.SourceURL(
+ std::string("a/") + base::FilePath(test_case.path).AsUTF8Unsafe());
+
+ // Find the first and last progress record.
+ size_t begin_index = records.size();
+ size_t end_index = records.size();
+ for (size_t j = 0; j < records.size(); ++j) {
+ if (records[j].url == src_url) {
+ if (begin_index == records.size())
+ begin_index = j;
+ end_index = j;
+ }
+ }
+
+ // The record should be found.
+ ASSERT_NE(begin_index, records.size());
+ ASSERT_NE(end_index, records.size());
+ ASSERT_NE(begin_index, end_index);
+
+ EXPECT_EQ(FileSystemOperation::BEGIN_COPY_ENTRY,
+ records[begin_index].type);
+ EXPECT_EQ(FileSystemOperation::END_COPY_ENTRY, records[end_index].type);
+
+ if (test_case.is_directory) {
+ // For directory copy, the progress shouldn't be interlaced.
+ EXPECT_EQ(begin_index + 1, end_index);
+ } else {
+ // PROGRESS event's size should be assending order.
+ int64 current_size = 0;
+ for (size_t j = begin_index + 1; j < end_index; ++j) {
+ if (records[j].url == src_url) {
+ EXPECT_EQ(FileSystemOperation::PROGRESS, records[j].type);
+ EXPECT_GE(records[j].size, current_size);
+ current_size = records[j].size;
+ }
+ }
+ }
+ }
+}
+
} // namespace fileapi
diff --git a/webkit/browser/fileapi/file_system_operation_impl.cc b/webkit/browser/fileapi/file_system_operation_impl.cc
index 5b1c228..a4c60e4 100644
--- a/webkit/browser/fileapi/file_system_operation_impl.cc
+++ b/webkit/browser/fileapi/file_system_operation_impl.cc
@@ -80,6 +80,7 @@ void FileSystemOperationImpl::Copy(
file_system_context(),
src_url, dest_url,
CopyOrMoveOperationDelegate::OPERATION_COPY,
+ progress_callback,
base::Bind(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback)));
recursive_operation_delegate_->RunRecursively();
@@ -95,6 +96,7 @@ void FileSystemOperationImpl::Move(const FileSystemURL& src_url,
file_system_context(),
src_url, dest_url,
CopyOrMoveOperationDelegate::OPERATION_MOVE,
+ FileSystemOperation::CopyProgressCallback(),
base::Bind(&FileSystemOperationImpl::DidFinishOperation,
weak_factory_.GetWeakPtr(), callback)));
recursive_operation_delegate_->RunRecursively();
@@ -284,7 +286,6 @@ void FileSystemOperationImpl::CopyFileLocal(
DCHECK(SetPendingOperationType(kOperationCopy));
DCHECK(src_url.IsInSameFileSystem(dest_url));
- // TODO(hidehiko): Support progress_callback.
GetUsageAndQuotaThenRunTask(
dest_url,
base::Bind(&FileSystemOperationImpl::DoCopyFileLocal,
diff --git a/webkit/browser/fileapi/file_system_url.h b/webkit/browser/fileapi/file_system_url.h
index 36b862e..d6443e6 100644
--- a/webkit/browser/fileapi/file_system_url.h
+++ b/webkit/browser/fileapi/file_system_url.h
@@ -130,6 +130,10 @@ class WEBKIT_STORAGE_BROWSER_EXPORT FileSystemURL {
bool operator==(const FileSystemURL& that) const;
+ bool operator!=(const FileSystemURL& that) const {
+ return !(*this == that);
+ }
+
struct WEBKIT_STORAGE_BROWSER_EXPORT Comparator {
bool operator() (const FileSystemURL& lhs, const FileSystemURL& rhs) const;
};