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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/browser/fileapi/copy_or_move_operation_delegate.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/browser/fileapi/copy_or_move_operation_delegate.h" 5 #include "webkit/browser/fileapi/copy_or_move_operation_delegate.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" 9 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
10 #include "webkit/browser/fileapi/file_system_context.h" 10 #include "webkit/browser/fileapi/file_system_context.h"
11 #include "webkit/browser/fileapi/file_system_operation_runner.h" 11 #include "webkit/browser/fileapi/file_system_operation_runner.h"
12 #include "webkit/browser/fileapi/file_system_url.h" 12 #include "webkit/browser/fileapi/file_system_url.h"
13 #include "webkit/browser/fileapi/recursive_operation_delegate.h" 13 #include "webkit/browser/fileapi/recursive_operation_delegate.h"
14 #include "webkit/common/blob/shareable_file_reference.h" 14 #include "webkit/common/blob/shareable_file_reference.h"
15 #include "webkit/common/fileapi/file_system_util.h" 15 #include "webkit/common/fileapi/file_system_util.h"
16 16
17 namespace fileapi { 17 namespace fileapi {
18 18
19 class CopyOrMoveOperationDelegate::CopyOrMoveImpl {
20 public:
21 virtual ~CopyOrMoveImpl() {}
22 virtual void Run(
23 const CopyOrMoveOperationDelegate::StatusCallback& callback) = 0;
24 protected:
25 CopyOrMoveImpl() {}
26 DISALLOW_COPY_AND_ASSIGN(CopyOrMoveImpl);
27 };
28
29 namespace {
30
31 // Copies a file on a (same) file system. Just delegate the operation to
32 // |operation_runner|.
33 class CopyOrMoveOnSameFileSystemImpl
34 : public CopyOrMoveOperationDelegate::CopyOrMoveImpl {
35 public:
36 CopyOrMoveOnSameFileSystemImpl(
37 FileSystemOperationRunner* operation_runner,
38 CopyOrMoveOperationDelegate::OperationType operation_type,
39 const FileSystemURL& src_url,
40 const FileSystemURL& dest_url)
41 : operation_runner_(operation_runner),
42 operation_type_(operation_type),
43 src_url_(src_url),
44 dest_url_(dest_url) {
45 }
46
47 virtual void Run(
48 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE {
49 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_MOVE) {
50 operation_runner_->MoveFileLocal(src_url_, dest_url_, callback);
51 } else {
52 // TODO(hidehiko): Support progress callback.
53 operation_runner_->CopyFileLocal(
54 src_url_, dest_url_,
55 FileSystemOperationRunner::CopyFileProgressCallback(), callback);
56 }
57 }
58
59 private:
60 FileSystemOperationRunner* operation_runner_;
61 CopyOrMoveOperationDelegate::OperationType operation_type_;
62 FileSystemURL src_url_;
63 FileSystemURL dest_url_;
64 DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOnSameFileSystemImpl);
65 };
66
67 // Specifically for cross file system copy/move operation, this class creates
68 // a snapshot file, validates it if necessary, runs copying process,
69 // validates the created file, and removes source file for move (noop for
70 // copy).
71 class SnapshotCopyOrMoveImpl
72 : public CopyOrMoveOperationDelegate::CopyOrMoveImpl {
73 public:
74 SnapshotCopyOrMoveImpl(
75 FileSystemOperationRunner* operation_runner,
76 CopyOrMoveOperationDelegate::OperationType operation_type,
77 const FileSystemURL& src_url,
78 const FileSystemURL& dest_url,
79 CopyOrMoveFileValidatorFactory* validator_factory)
80 : operation_runner_(operation_runner),
81 operation_type_(operation_type),
82 src_url_(src_url),
83 dest_url_(dest_url),
84 validator_factory_(validator_factory),
85 weak_factory_(this) {
86 }
87
88 virtual void Run(
89 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE {
90 operation_runner_->CreateSnapshotFile(
91 src_url_,
92 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCreateSnapshot,
93 weak_factory_.GetWeakPtr(), callback));
94 }
95
96 private:
97 void RunAfterCreateSnapshot(
98 const CopyOrMoveOperationDelegate::StatusCallback& callback,
99 base::PlatformFileError error,
100 const base::PlatformFileInfo& file_info,
101 const base::FilePath& platform_path,
102 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
103 if (error != base::PLATFORM_FILE_OK) {
104 callback.Run(error);
105 return;
106 }
107
108 // For now we assume CreateSnapshotFile always return a valid local file
109 // path.
110 DCHECK(!platform_path.empty());
111
112 if (!validator_factory_) {
113 // No validation is needed.
114 RunAfterPreWriteValidation(
115 platform_path, file_ref, callback, base::PLATFORM_FILE_OK);
116 return;
117 }
118
119 // Run pre write validation.
120 PreWriteValidation(
121 platform_path,
122 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPreWriteValidation,
123 weak_factory_.GetWeakPtr(),
124 platform_path, file_ref, callback));
125 }
126
127 void RunAfterPreWriteValidation(
128 const base::FilePath& platform_path,
129 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
130 const CopyOrMoveOperationDelegate::StatusCallback& callback,
131 base::PlatformFileError error) {
132 if (error != base::PLATFORM_FILE_OK) {
133 callback.Run(error);
134 return;
135 }
136
137 // |file_ref| is unused but necessary to keep the file alive until
138 // CopyInForeignFile() is completed.
139 operation_runner_->CopyInForeignFile(
140 platform_path, dest_url_,
141 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCopyInForeignFile,
142 weak_factory_.GetWeakPtr(), file_ref, callback));
143 }
144
145 void RunAfterCopyInForeignFile(
146 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
147 const CopyOrMoveOperationDelegate::StatusCallback& callback,
148 base::PlatformFileError error) {
149 if (error != base::PLATFORM_FILE_OK) {
150 callback.Run(error);
151 return;
152 }
153
154 // |validator_| is NULL when the destination filesystem does not do
155 // validation.
156 if (!validator_) {
157 // No validation is needed.
158 RunAfterPostWriteValidation(callback, base::PLATFORM_FILE_OK);
159 return;
160 }
161
162 PostWriteValidation(
163 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPostWriteValidation,
164 weak_factory_.GetWeakPtr(), callback));
165 }
166
167 void RunAfterPostWriteValidation(
168 const CopyOrMoveOperationDelegate::StatusCallback& callback,
169 base::PlatformFileError error) {
170 if (error != base::PLATFORM_FILE_OK) {
171 // Failed to validate. Remove the destination file.
172 operation_runner_->Remove(
173 dest_url_, true /* recursive */,
174 base::Bind(&SnapshotCopyOrMoveImpl::DidRemoveDestForError,
175 weak_factory_.GetWeakPtr(), error, callback));
176 return;
177 }
178
179 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) {
180 callback.Run(base::PLATFORM_FILE_OK);
181 return;
182 }
183
184 DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_);
185
186 // Remove the source for finalizing move operation.
187 operation_runner_->Remove(
188 src_url_, true /* recursive */,
189 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterRemoveSourceForMove,
190 weak_factory_.GetWeakPtr(), callback));
191 }
192
193 void RunAfterRemoveSourceForMove(
194 const CopyOrMoveOperationDelegate::StatusCallback& callback,
195 base::PlatformFileError error) {
196 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
197 error = base::PLATFORM_FILE_OK;
198 callback.Run(error);
199 }
200
201 void DidRemoveDestForError(
202 base::PlatformFileError prior_error,
203 const CopyOrMoveOperationDelegate::StatusCallback& callback,
204 base::PlatformFileError error) {
205 if (error != base::PLATFORM_FILE_OK) {
206 VLOG(1) << "Error removing destination file after validation error: "
207 << error;
208 }
209 callback.Run(prior_error);
210 }
211
212 // Runs pre-write validation.
213 void PreWriteValidation(
214 const base::FilePath& platform_path,
215 const CopyOrMoveOperationDelegate::StatusCallback& callback) {
216 DCHECK(validator_factory_);
217 validator_.reset(
218 validator_factory_->CreateCopyOrMoveFileValidator(
219 src_url_, platform_path));
220 validator_->StartPreWriteValidation(callback);
221 }
222
223 // Runs post-write validation.
224 void PostWriteValidation(
225 const CopyOrMoveOperationDelegate::StatusCallback& callback) {
226 operation_runner_->CreateSnapshotFile(
227 dest_url_,
228 base::Bind(
229 &SnapshotCopyOrMoveImpl::PostWriteValidationAfterCreateSnapshotFile,
230 weak_factory_.GetWeakPtr(), callback));
231 }
232
233 void PostWriteValidationAfterCreateSnapshotFile(
234 const CopyOrMoveOperationDelegate::StatusCallback& callback,
235 base::PlatformFileError error,
236 const base::PlatformFileInfo& file_info,
237 const base::FilePath& platform_path,
238 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
239 if (error != base::PLATFORM_FILE_OK) {
240 callback.Run(error);
241 return;
242 }
243
244 DCHECK(validator_);
245 // Note: file_ref passed here to keep the file alive until after
246 // the StartPostWriteValidation operation finishes.
247 validator_->StartPostWriteValidation(
248 platform_path,
249 base::Bind(&SnapshotCopyOrMoveImpl::DidPostWriteValidation,
250 weak_factory_.GetWeakPtr(), file_ref, callback));
251 }
252
253 // |file_ref| is unused; it is passed here to make sure the reference is
254 // alive until after post-write validation is complete.
255 void DidPostWriteValidation(
256 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
257 const CopyOrMoveOperationDelegate::StatusCallback& callback,
258 base::PlatformFileError error) {
259 callback.Run(error);
260 }
261
262 FileSystemOperationRunner* operation_runner_;
263 CopyOrMoveOperationDelegate::OperationType operation_type_;
264 FileSystemURL src_url_;
265 FileSystemURL dest_url_;
266 CopyOrMoveFileValidatorFactory* validator_factory_;
267 scoped_ptr<CopyOrMoveFileValidator> validator_;
268
269 base::WeakPtrFactory<SnapshotCopyOrMoveImpl> weak_factory_;
270 DISALLOW_COPY_AND_ASSIGN(SnapshotCopyOrMoveImpl);
271 };
272
273 } // namespace
274
275
19 CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate( 276 CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate(
20 FileSystemContext* file_system_context, 277 FileSystemContext* file_system_context,
21 const FileSystemURL& src_root, 278 const FileSystemURL& src_root,
22 const FileSystemURL& dest_root, 279 const FileSystemURL& dest_root,
23 OperationType operation_type, 280 OperationType operation_type,
24 const StatusCallback& callback) 281 const StatusCallback& callback)
25 : RecursiveOperationDelegate(file_system_context), 282 : RecursiveOperationDelegate(file_system_context),
26 src_root_(src_root), 283 src_root_(src_root),
27 dest_root_(dest_root), 284 dest_root_(dest_root),
28 operation_type_(operation_type), 285 operation_type_(operation_type),
29 callback_(callback), 286 callback_(callback),
30 weak_factory_(this) { 287 weak_factory_(this) {
31 same_file_system_ = src_root_.IsInSameFileSystem(dest_root_); 288 same_file_system_ = src_root_.IsInSameFileSystem(dest_root_);
32 } 289 }
33 290
34 CopyOrMoveOperationDelegate::~CopyOrMoveOperationDelegate() { 291 CopyOrMoveOperationDelegate::~CopyOrMoveOperationDelegate() {
292 STLDeleteElements(&running_copy_set_);
35 } 293 }
36 294
37 void CopyOrMoveOperationDelegate::Run() { 295 void CopyOrMoveOperationDelegate::Run() {
38 // Not supported; this should never be called. 296 // Not supported; this should never be called.
39 NOTREACHED(); 297 NOTREACHED();
40 } 298 }
41 299
42 void CopyOrMoveOperationDelegate::RunRecursively() { 300 void CopyOrMoveOperationDelegate::RunRecursively() {
43 // Perform light-weight checks first. 301 // Perform light-weight checks first.
44 302
45 // It is an error to try to copy/move an entry into its child. 303 // It is an error to try to copy/move an entry into its child.
46 if (same_file_system_ && src_root_.path().IsParent(dest_root_.path())) { 304 if (same_file_system_ && src_root_.path().IsParent(dest_root_.path())) {
47 callback_.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); 305 callback_.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
48 return; 306 return;
49 } 307 }
50 308
51 // It is an error to copy/move an entry into the same path. 309 // It is an error to copy/move an entry into the same path.
52 if (same_file_system_ && src_root_.path() == dest_root_.path()) { 310 if (same_file_system_ && src_root_.path() == dest_root_.path()) {
53 callback_.Run(base::PLATFORM_FILE_ERROR_EXISTS); 311 callback_.Run(base::PLATFORM_FILE_ERROR_EXISTS);
54 return; 312 return;
55 } 313 }
56 314
57 // First try to copy/move it as a file. 315 // First try to copy/move it as a file.
58 CopyOrMoveFile(URLPair(src_root_, dest_root_), 316 CopyOrMoveFile(src_root_, dest_root_,
59 base::Bind(&CopyOrMoveOperationDelegate::DidTryCopyOrMoveFile, 317 base::Bind(&CopyOrMoveOperationDelegate::DidTryCopyOrMoveFile,
60 weak_factory_.GetWeakPtr())); 318 weak_factory_.GetWeakPtr()));
61 } 319 }
62 320
63 void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, 321 void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url,
64 const StatusCallback& callback) { 322 const StatusCallback& callback) {
65 CopyOrMoveFile(URLPair(src_url, CreateDestURL(src_url)), callback); 323 CopyOrMoveFile(src_url, CreateDestURL(src_url), callback);
66 } 324 }
67 325
68 void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url, 326 void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url,
69 const StatusCallback& callback) { 327 const StatusCallback& callback) {
70 FileSystemURL dest_url = CreateDestURL(src_url); 328 FileSystemURL dest_url = CreateDestURL(src_url);
71 329
72 // If operation_type == Move we may need to record directories and 330 // If operation_type == Move we may need to record directories and
73 // restore directory timestamps in the end, though it may have 331 // restore directory timestamps in the end, though it may have
74 // negative performance impact. 332 // negative performance impact.
75 // See http://crbug.com/171284 for more details. 333 // See http://crbug.com/171284 for more details.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // Start to process the source directory recursively. 367 // Start to process the source directory recursively.
110 // TODO(kinuko): This could be too expensive for same_file_system_==true 368 // TODO(kinuko): This could be too expensive for same_file_system_==true
111 // and operation==MOVE case, probably we can just rename the root directory. 369 // and operation==MOVE case, probably we can just rename the root directory.
112 // http://crbug.com/172187 370 // http://crbug.com/172187
113 StartRecursiveOperation( 371 StartRecursiveOperation(
114 src_root_, 372 src_root_,
115 base::Bind(&CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir, 373 base::Bind(&CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir,
116 weak_factory_.GetWeakPtr(), src_root_, callback_)); 374 weak_factory_.GetWeakPtr(), src_root_, callback_));
117 } 375 }
118 376
119 void CopyOrMoveOperationDelegate::CopyOrMoveFile(
120 const URLPair& url_pair,
121 const StatusCallback& callback) {
122 // Same filesystem case.
123 if (same_file_system_) {
124 if (operation_type_ == OPERATION_MOVE) {
125 operation_runner()->MoveFileLocal(url_pair.src, url_pair.dest, callback);
126 } else {
127 // TODO(hidehiko): Support progress callback.
128 operation_runner()->CopyFileLocal(
129 url_pair.src, url_pair.dest,
130 FileSystemOperationRunner::CopyFileProgressCallback(), callback);
131 }
132 return;
133 }
134
135 // Cross filesystem case.
136 // Perform CreateSnapshotFile, CopyInForeignFile and then calls
137 // copy_callback which removes the source file if operation_type == MOVE.
138 StatusCallback copy_callback =
139 base::Bind(&CopyOrMoveOperationDelegate::DidFinishCopy,
140 weak_factory_.GetWeakPtr(), url_pair, callback);
141 operation_runner()->CreateSnapshotFile(
142 url_pair.src,
143 base::Bind(&CopyOrMoveOperationDelegate::DidCreateSnapshot,
144 weak_factory_.GetWeakPtr(), url_pair, copy_callback));
145 }
146
147 void CopyOrMoveOperationDelegate::DidCreateSnapshot(
148 const URLPair& url_pair,
149 const StatusCallback& callback,
150 base::PlatformFileError error,
151 const base::PlatformFileInfo& file_info,
152 const base::FilePath& platform_path,
153 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
154 if (error != base::PLATFORM_FILE_OK) {
155 callback.Run(error);
156 return;
157 }
158 current_file_ref_ = file_ref;
159
160 // For now we assume CreateSnapshotFile always return a valid local file path.
161 // TODO(kinuko): Otherwise create a FileStreamReader to perform a copy/move.
162 DCHECK(!platform_path.empty());
163
164 CopyOrMoveFileValidatorFactory* factory =
165 file_system_context()->GetCopyOrMoveFileValidatorFactory(
166 dest_root_.type(), &error);
167 if (error != base::PLATFORM_FILE_OK) {
168 callback.Run(error);
169 return;
170 }
171 if (!factory) {
172 DidValidateFile(url_pair.dest, callback, file_info, platform_path, error);
173 return;
174 }
175
176 validator_.reset(
177 factory->CreateCopyOrMoveFileValidator(url_pair.src, platform_path));
178 validator_->StartPreWriteValidation(
179 base::Bind(&CopyOrMoveOperationDelegate::DidValidateFile,
180 weak_factory_.GetWeakPtr(),
181 url_pair.dest, callback, file_info, platform_path));
182 }
183
184 void CopyOrMoveOperationDelegate::DidValidateFile(
185 const FileSystemURL& dest,
186 const StatusCallback& callback,
187 const base::PlatformFileInfo& file_info,
188 const base::FilePath& platform_path,
189 base::PlatformFileError error) {
190 if (error != base::PLATFORM_FILE_OK) {
191 callback.Run(error);
192 return;
193 }
194
195 operation_runner()->CopyInForeignFile(platform_path, dest, callback);
196 }
197
198 void CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir( 377 void CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir(
199 const FileSystemURL& src, 378 const FileSystemURL& src,
200 const StatusCallback& callback, 379 const StatusCallback& callback,
201 base::PlatformFileError error) { 380 base::PlatformFileError error) {
202 if (error != base::PLATFORM_FILE_OK || 381 if (error != base::PLATFORM_FILE_OK ||
203 operation_type_ == OPERATION_COPY) { 382 operation_type_ == OPERATION_COPY) {
204 callback.Run(error); 383 callback.Run(error);
205 return; 384 return;
206 } 385 }
207 386
208 DCHECK_EQ(OPERATION_MOVE, operation_type_); 387 DCHECK_EQ(OPERATION_MOVE, operation_type_);
209 388
210 // Remove the source for finalizing move operation. 389 // Remove the source for finalizing move operation.
211 operation_runner()->Remove( 390 operation_runner()->Remove(
212 src, true /* recursive */, 391 src, true /* recursive */,
213 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, 392 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove,
214 weak_factory_.GetWeakPtr(), callback)); 393 weak_factory_.GetWeakPtr(), callback));
215 } 394 }
216 395
217 void CopyOrMoveOperationDelegate::DidFinishCopy(
218 const URLPair& url_pair,
219 const StatusCallback& callback,
220 base::PlatformFileError error) {
221 if (error != base::PLATFORM_FILE_OK) {
222 callback.Run(error);
223 return;
224 }
225
226 // |validator_| is NULL in the same-filesystem case or when the destination
227 // filesystem does not do validation.
228 if (!validator_.get()) {
229 scoped_refptr<webkit_blob::ShareableFileReference> file_ref;
230 DidPostWriteValidation(url_pair, callback, file_ref,
231 base::PLATFORM_FILE_OK);
232 return;
233 }
234
235 DCHECK(!same_file_system_);
236 operation_runner()->CreateSnapshotFile(
237 url_pair.dest,
238 base::Bind(&CopyOrMoveOperationDelegate::DoPostWriteValidation,
239 weak_factory_.GetWeakPtr(), url_pair, callback));
240 }
241
242 void CopyOrMoveOperationDelegate::DoPostWriteValidation(
243 const URLPair& url_pair,
244 const StatusCallback& callback,
245 base::PlatformFileError error,
246 const base::PlatformFileInfo& file_info,
247 const base::FilePath& platform_path,
248 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
249 if (error != base::PLATFORM_FILE_OK) {
250 operation_runner()->Remove(
251 url_pair.dest, true,
252 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveDestForError,
253 weak_factory_.GetWeakPtr(), error, callback));
254 return;
255 }
256
257 DCHECK(validator_.get());
258 // Note: file_ref passed here to keep the file alive until after
259 // the StartPostWriteValidation operation finishes.
260 validator_->StartPostWriteValidation(
261 platform_path,
262 base::Bind(&CopyOrMoveOperationDelegate::DidPostWriteValidation,
263 weak_factory_.GetWeakPtr(), url_pair, callback, file_ref));
264 }
265
266 // |file_ref| is unused; it is passed here to make sure the reference is
267 // alive until after post-write validation is complete.
268 void CopyOrMoveOperationDelegate::DidPostWriteValidation(
269 const URLPair& url_pair,
270 const StatusCallback& callback,
271 const scoped_refptr<webkit_blob::ShareableFileReference>& /*file_ref*/,
272 base::PlatformFileError error) {
273 if (error != base::PLATFORM_FILE_OK) {
274 operation_runner()->Remove(
275 url_pair.dest, true,
276 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveDestForError,
277 weak_factory_.GetWeakPtr(), error, callback));
278 return;
279 }
280
281 if (operation_type_ == OPERATION_COPY) {
282 callback.Run(error);
283 return;
284 }
285
286 DCHECK_EQ(OPERATION_MOVE, operation_type_);
287
288 // Remove the source for finalizing move operation.
289 operation_runner()->Remove(
290 url_pair.src, true /* recursive */,
291 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove,
292 weak_factory_.GetWeakPtr(), callback));
293 }
294
295 void CopyOrMoveOperationDelegate::DidRemoveSourceForMove( 396 void CopyOrMoveOperationDelegate::DidRemoveSourceForMove(
296 const StatusCallback& callback, 397 const StatusCallback& callback,
297 base::PlatformFileError error) { 398 base::PlatformFileError error) {
298 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) 399 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
299 error = base::PLATFORM_FILE_OK; 400 error = base::PLATFORM_FILE_OK;
300 callback.Run(error); 401 callback.Run(error);
301 } 402 }
302 403
404 void CopyOrMoveOperationDelegate::CopyOrMoveFile(
405 const FileSystemURL& src_url,
406 const FileSystemURL& dest_url,
407 const StatusCallback& callback) {
408 CopyOrMoveImpl* impl = NULL;
409 if (same_file_system_) {
410 impl = new CopyOrMoveOnSameFileSystemImpl(
411 operation_runner(), operation_type_, src_url, dest_url);
412 } else {
413 // Cross filesystem case.
414 // TODO(hidehiko): Support stream based copy. crbug.com/279287.
415 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
416 CopyOrMoveFileValidatorFactory* validator_factory =
417 file_system_context()->GetCopyOrMoveFileValidatorFactory(
418 dest_root_.type(), &error);
419 if (error != base::PLATFORM_FILE_OK) {
420 callback.Run(error);
421 return;
422 }
423
424 impl = new SnapshotCopyOrMoveImpl(
425 operation_runner(), operation_type_, src_url, dest_url,
426 validator_factory);
427 }
428
429 // Register the running task.
430 running_copy_set_.insert(impl);
431 impl->Run(base::Bind(&CopyOrMoveOperationDelegate::DidCopyOrMoveFile,
432 weak_factory_.GetWeakPtr(), impl, callback));
433 }
434
435 void CopyOrMoveOperationDelegate::DidCopyOrMoveFile(
436 CopyOrMoveImpl* impl,
437 const StatusCallback& callback,
438 base::PlatformFileError error) {
439 running_copy_set_.erase(impl);
440 delete impl;
441 callback.Run(error);
442 }
443
303 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( 444 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL(
304 const FileSystemURL& src_url) const { 445 const FileSystemURL& src_url) const {
305 DCHECK_EQ(src_root_.type(), src_url.type()); 446 DCHECK_EQ(src_root_.type(), src_url.type());
306 DCHECK_EQ(src_root_.origin(), src_url.origin()); 447 DCHECK_EQ(src_root_.origin(), src_url.origin());
307 448
308 base::FilePath relative = dest_root_.virtual_path(); 449 base::FilePath relative = dest_root_.virtual_path();
309 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), 450 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(),
310 &relative); 451 &relative);
311 return file_system_context()->CreateCrackedFileSystemURL( 452 return file_system_context()->CreateCrackedFileSystemURL(
312 dest_root_.origin(), 453 dest_root_.origin(),
313 dest_root_.mount_type(), 454 dest_root_.mount_type(),
314 relative); 455 relative);
315 } 456 }
316 457
317 void CopyOrMoveOperationDelegate::DidRemoveDestForError(
318 base::PlatformFileError prior_error,
319 const StatusCallback& callback,
320 base::PlatformFileError error) {
321 if (error != base::PLATFORM_FILE_OK) {
322 VLOG(1) << "Error removing destination file after validation error: "
323 << error;
324 }
325 callback.Run(prior_error);
326 }
327
328 } // namespace fileapi 458 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/browser/fileapi/copy_or_move_operation_delegate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698