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

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
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 // 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.
20 class CopyOrMoveOperationDelegate::CopyOrMoveImpl {
21 public:
22 virtual ~CopyOrMoveImpl() {}
23 virtual void Run(
24 const CopyOrMoveOperationDelegate::StatusCallback& callback) = 0;
25 protected:
26 CopyOrMoveImpl() {}
27 DISALLOW_COPY_AND_ASSIGN(CopyOrMoveImpl);
28 };
29
30 namespace {
31
32 // Copies a file on a (same) file system. Just delegate the operation to
33 // |operation_runner|.
34 class CopyOrMoveOnSameFileSystemImpl
35 : public CopyOrMoveOperationDelegate::CopyOrMoveImpl {
36 public:
37 CopyOrMoveOnSameFileSystemImpl(
38 FileSystemOperationRunner* operation_runner,
39 CopyOrMoveOperationDelegate::OperationType operation_type,
40 const FileSystemURL& src_url,
41 const FileSystemURL& dest_url)
42 : operation_runner_(operation_runner),
43 operation_type_(operation_type),
44 src_url_(src_url),
45 dest_url_(dest_url) {
46 }
47
48 virtual void Run(
49 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE {
50 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_MOVE) {
51 operation_runner_->MoveFileLocal(src_url_, dest_url_, callback);
52 } else {
53 // TODO(hidehiko): Support progress callback.
54 operation_runner_->CopyFileLocal(
55 src_url_, dest_url_,
56 FileSystemOperationRunner::CopyFileProgressCallback(), callback);
57 }
58 }
59
60 private:
61 FileSystemOperationRunner* operation_runner_;
62 CopyOrMoveOperationDelegate::OperationType operation_type_;
63 FileSystemURL src_url_;
64 FileSystemURL dest_url_;
65 DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOnSameFileSystemImpl);
66 };
67
68 // 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.
69 // a snapshot file, validate it if necessary, run copying process,
70 // 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.
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,
kinuko 2013/09/09 16:12:38 nit: extra space
hidehiko 2013/09/09 16:55:35 Oops done.
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 // 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.
111 DCHECK(!platform_path.empty());
112
113 if (!validator_factory_) {
114 // No validation is needed.
115 RunAfterPreWriteValidation(
116 platform_path, file_ref, callback, base::PLATFORM_FILE_OK);
117 return;
118 }
119
120 // Runs pre write validation.
kinuko 2013/09/09 16:12:38 nit: Runs -> Run
hidehiko 2013/09/09 16:55:35 Done.
121 PreWriteValidation(
122 platform_path,
123 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPreWriteValidation,
124 weak_factory_.GetWeakPtr(),
125 platform_path, file_ref, callback));
126 }
127
128 void RunAfterPreWriteValidation(
129 const base::FilePath& platform_path,
130 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
131 const CopyOrMoveOperationDelegate::StatusCallback& callback,
132 base::PlatformFileError error) {
133 if (error != base::PLATFORM_FILE_OK) {
134 callback.Run(error);
135 return;
136 }
137
138 // |file_ref| is unused but necessary to keep the file alive until
139 // CopyInForeignFile() is completed.
140 operation_runner_->CopyInForeignFile(
141 platform_path, dest_url_,
142 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCopyInForeignFile,
143 weak_factory_.GetWeakPtr(), file_ref, callback));
144 }
145
146 void RunAfterCopyInForeignFile(
147 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
148 const CopyOrMoveOperationDelegate::StatusCallback& callback,
149 base::PlatformFileError error) {
150 if (error != base::PLATFORM_FILE_OK) {
151 callback.Run(error);
152 return;
153 }
154
155 // |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.
156 // validation.
157 if (!validator_) {
158 // No validation is needed.
159 RunAfterPostWriteValidation(callback, base::PLATFORM_FILE_OK);
160 return;
161 }
162
163 PostWriteValidation(
164 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPostWriteValidation,
165 weak_factory_.GetWeakPtr(), callback));
166 }
167
168 void RunAfterPostWriteValidation(
169 const CopyOrMoveOperationDelegate::StatusCallback& callback,
170 base::PlatformFileError error) {
171 if (error != base::PLATFORM_FILE_OK) {
172 // Failed to validate. Remove the destination file.
173 operation_runner_->Remove(
174 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.
175 base::Bind(&SnapshotCopyOrMoveImpl::DidRemoveDestForError,
176 weak_factory_.GetWeakPtr(), error, callback));
177 return;
178 }
179
180 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) {
181 callback.Run(base::PLATFORM_FILE_OK);
182 return;
183 }
184
185 DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_);
186
187 // Remove the source for finalizing move operation.
188 operation_runner_->Remove(
189 src_url_, true /* recursive */,
190 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterRemoveSourceForMove,
191 weak_factory_.GetWeakPtr(), callback));
192 }
193
194 void RunAfterRemoveSourceForMove(
195 const CopyOrMoveOperationDelegate::StatusCallback& callback,
196 base::PlatformFileError error) {
197 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
198 error = base::PLATFORM_FILE_OK;
199 callback.Run(error);
200 }
201
202 void DidRemoveDestForError(
203 base::PlatformFileError prior_error,
204 const CopyOrMoveOperationDelegate::StatusCallback& callback,
205 base::PlatformFileError error) {
206 if (error != base::PLATFORM_FILE_OK) {
207 VLOG(1) << "Error removing destination file after validation error: "
208 << error;
209 }
210 callback.Run(prior_error);
211 }
212
213 // Runs pre-write validation.
214 void PreWriteValidation(
215 const base::FilePath& platform_path,
216 const CopyOrMoveOperationDelegate::StatusCallback& callback) {
217 DCHECK(validator_factory_);
218 validator_.reset(
219 validator_factory_->CreateCopyOrMoveFileValidator(
220 src_url_, platform_path));
221 validator_->StartPreWriteValidation(callback);
222 }
223
224 // Runs post-write validation.
225 void PostWriteValidation(
226 const CopyOrMoveOperationDelegate::StatusCallback& callback) {
227 operation_runner_->CreateSnapshotFile(
228 dest_url_,
229 base::Bind(
230 &SnapshotCopyOrMoveImpl::PostWriteValidationAfterCreateSnapshotFile,
231 weak_factory_.GetWeakPtr(), callback));
232 }
233
234 void PostWriteValidationAfterCreateSnapshotFile(
235 const CopyOrMoveOperationDelegate::StatusCallback& callback,
236 base::PlatformFileError error,
237 const base::PlatformFileInfo& file_info,
238 const base::FilePath& platform_path,
239 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
240 if (error != base::PLATFORM_FILE_OK) {
241 callback.Run(error);
242 return;
243 }
244
245 DCHECK(validator_);
246 // Note: file_ref passed here to keep the file alive until after
247 // the StartPostWriteValidation operation finishes.
248 validator_->StartPostWriteValidation(
249 platform_path,
250 base::Bind(&SnapshotCopyOrMoveImpl::DidPostWriteValidation,
251 weak_factory_.GetWeakPtr(), file_ref, callback));
252 }
253
254 // |file_ref| is unused; it is passed here to make sure the reference is
255 // alive until after post-write validation is complete.
256 void DidPostWriteValidation(
257 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref,
258 const CopyOrMoveOperationDelegate::StatusCallback& callback,
259 base::PlatformFileError error) {
260 callback.Run(error);
261 }
262
263 FileSystemOperationRunner* operation_runner_;
264 CopyOrMoveOperationDelegate::OperationType operation_type_;
265 FileSystemURL src_url_;
266 FileSystemURL dest_url_;
267 CopyOrMoveFileValidatorFactory* validator_factory_;
268 scoped_ptr<CopyOrMoveFileValidator> validator_;
269
270 base::WeakPtrFactory<SnapshotCopyOrMoveImpl> weak_factory_;
271 DISALLOW_COPY_AND_ASSIGN(SnapshotCopyOrMoveImpl);
272 };
273
274 } // namespace
275
276
19 CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate( 277 CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate(
20 FileSystemContext* file_system_context, 278 FileSystemContext* file_system_context,
21 const FileSystemURL& src_root, 279 const FileSystemURL& src_root,
22 const FileSystemURL& dest_root, 280 const FileSystemURL& dest_root,
23 OperationType operation_type, 281 OperationType operation_type,
24 const StatusCallback& callback) 282 const StatusCallback& callback)
25 : RecursiveOperationDelegate(file_system_context), 283 : RecursiveOperationDelegate(file_system_context),
26 src_root_(src_root), 284 src_root_(src_root),
27 dest_root_(dest_root), 285 dest_root_(dest_root),
28 operation_type_(operation_type), 286 operation_type_(operation_type),
29 callback_(callback), 287 callback_(callback),
30 weak_factory_(this) { 288 weak_factory_(this) {
31 same_file_system_ = src_root_.IsInSameFileSystem(dest_root_); 289 same_file_system_ = src_root_.IsInSameFileSystem(dest_root_);
32 } 290 }
33 291
34 CopyOrMoveOperationDelegate::~CopyOrMoveOperationDelegate() { 292 CopyOrMoveOperationDelegate::~CopyOrMoveOperationDelegate() {
293 STLDeleteElements(&running_copy_set_);
35 } 294 }
36 295
37 void CopyOrMoveOperationDelegate::Run() { 296 void CopyOrMoveOperationDelegate::Run() {
38 // Not supported; this should never be called. 297 // Not supported; this should never be called.
39 NOTREACHED(); 298 NOTREACHED();
40 } 299 }
41 300
42 void CopyOrMoveOperationDelegate::RunRecursively() { 301 void CopyOrMoveOperationDelegate::RunRecursively() {
43 // Perform light-weight checks first. 302 // Perform light-weight checks first.
44 303
45 // It is an error to try to copy/move an entry into its child. 304 // 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())) { 305 if (same_file_system_ && src_root_.path().IsParent(dest_root_.path())) {
47 callback_.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION); 306 callback_.Run(base::PLATFORM_FILE_ERROR_INVALID_OPERATION);
48 return; 307 return;
49 } 308 }
50 309
51 // It is an error to copy/move an entry into the same path. 310 // It is an error to copy/move an entry into the same path.
52 if (same_file_system_ && src_root_.path() == dest_root_.path()) { 311 if (same_file_system_ && src_root_.path() == dest_root_.path()) {
53 callback_.Run(base::PLATFORM_FILE_ERROR_EXISTS); 312 callback_.Run(base::PLATFORM_FILE_ERROR_EXISTS);
54 return; 313 return;
55 } 314 }
56 315
57 // First try to copy/move it as a file. 316 // First try to copy/move it as a file.
58 CopyOrMoveFile(URLPair(src_root_, dest_root_), 317 CopyOrMoveFile(src_root_, dest_root_,
59 base::Bind(&CopyOrMoveOperationDelegate::DidTryCopyOrMoveFile, 318 base::Bind(&CopyOrMoveOperationDelegate::DidTryCopyOrMoveFile,
60 weak_factory_.GetWeakPtr())); 319 weak_factory_.GetWeakPtr()));
61 } 320 }
62 321
63 void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, 322 void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url,
64 const StatusCallback& callback) { 323 const StatusCallback& callback) {
65 CopyOrMoveFile(URLPair(src_url, CreateDestURL(src_url)), callback); 324 CopyOrMoveFile(src_url, CreateDestURL(src_url), callback);
66 } 325 }
67 326
68 void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url, 327 void CopyOrMoveOperationDelegate::ProcessDirectory(const FileSystemURL& src_url,
69 const StatusCallback& callback) { 328 const StatusCallback& callback) {
70 FileSystemURL dest_url = CreateDestURL(src_url); 329 FileSystemURL dest_url = CreateDestURL(src_url);
71 330
72 // If operation_type == Move we may need to record directories and 331 // If operation_type == Move we may need to record directories and
73 // restore directory timestamps in the end, though it may have 332 // restore directory timestamps in the end, though it may have
74 // negative performance impact. 333 // negative performance impact.
75 // See http://crbug.com/171284 for more details. 334 // 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. 368 // Start to process the source directory recursively.
110 // TODO(kinuko): This could be too expensive for same_file_system_==true 369 // 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. 370 // and operation==MOVE case, probably we can just rename the root directory.
112 // http://crbug.com/172187 371 // http://crbug.com/172187
113 StartRecursiveOperation( 372 StartRecursiveOperation(
114 src_root_, 373 src_root_,
115 base::Bind(&CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir, 374 base::Bind(&CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir,
116 weak_factory_.GetWeakPtr(), src_root_, callback_)); 375 weak_factory_.GetWeakPtr(), src_root_, callback_));
117 } 376 }
118 377
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( 378 void CopyOrMoveOperationDelegate::DidFinishRecursiveCopyDir(
199 const FileSystemURL& src, 379 const FileSystemURL& src,
200 const StatusCallback& callback, 380 const StatusCallback& callback,
201 base::PlatformFileError error) { 381 base::PlatformFileError error) {
202 if (error != base::PLATFORM_FILE_OK || 382 if (error != base::PLATFORM_FILE_OK ||
203 operation_type_ == OPERATION_COPY) { 383 operation_type_ == OPERATION_COPY) {
204 callback.Run(error); 384 callback.Run(error);
205 return; 385 return;
206 } 386 }
207 387
208 DCHECK_EQ(OPERATION_MOVE, operation_type_); 388 DCHECK_EQ(OPERATION_MOVE, operation_type_);
209 389
210 // Remove the source for finalizing move operation. 390 // Remove the source for finalizing move operation.
211 operation_runner()->Remove( 391 operation_runner()->Remove(
212 src, true /* recursive */, 392 src, true /* recursive */,
213 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, 393 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove,
214 weak_factory_.GetWeakPtr(), callback)); 394 weak_factory_.GetWeakPtr(), callback));
215 } 395 }
216 396
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( 397 void CopyOrMoveOperationDelegate::DidRemoveSourceForMove(
296 const StatusCallback& callback, 398 const StatusCallback& callback,
297 base::PlatformFileError error) { 399 base::PlatformFileError error) {
298 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND) 400 if (error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
299 error = base::PLATFORM_FILE_OK; 401 error = base::PLATFORM_FILE_OK;
300 callback.Run(error); 402 callback.Run(error);
301 } 403 }
302 404
405 void CopyOrMoveOperationDelegate::CopyOrMoveFile(
406 const FileSystemURL& src_url,
407 const FileSystemURL& dest_url,
408 const StatusCallback& callback) {
409 CopyOrMoveImpl* impl = NULL;
410 if (same_file_system_) {
411 impl = new CopyOrMoveOnSameFileSystemImpl(
412 operation_runner(), operation_type_, src_url, dest_url);
413 } else {
414 // Cross filesystem case.
415 // TODO(hidehiko): Support stream based copy. crbug.com/279287.
416 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
417 CopyOrMoveFileValidatorFactory* validator_factory =
418 file_system_context()->GetCopyOrMoveFileValidatorFactory(
419 dest_root_.type(), &error);
420 if (error != base::PLATFORM_FILE_OK) {
421 callback.Run(error);
422 return;
423 }
424
425 impl = new SnapshotCopyOrMoveImpl(
426 operation_runner(), operation_type_, src_url, dest_url,
427 validator_factory);
428 }
429
430 // Register the running task.
431 running_copy_set_.insert(impl);
432 impl->Run(base::Bind(&CopyOrMoveOperationDelegate::DidCopyOrMoveFile,
433 weak_factory_.GetWeakPtr(), impl, callback));
434 }
435
436 void CopyOrMoveOperationDelegate::DidCopyOrMoveFile(
437 CopyOrMoveImpl* impl,
438 const StatusCallback& callback,
439 base::PlatformFileError error) {
440 running_copy_set_.erase(impl);
441 delete impl;
442 callback.Run(error);
443 }
444
303 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( 445 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL(
304 const FileSystemURL& src_url) const { 446 const FileSystemURL& src_url) const {
305 DCHECK_EQ(src_root_.type(), src_url.type()); 447 DCHECK_EQ(src_root_.type(), src_url.type());
306 DCHECK_EQ(src_root_.origin(), src_url.origin()); 448 DCHECK_EQ(src_root_.origin(), src_url.origin());
307 449
308 base::FilePath relative = dest_root_.virtual_path(); 450 base::FilePath relative = dest_root_.virtual_path();
309 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), 451 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(),
310 &relative); 452 &relative);
311 return file_system_context()->CreateCrackedFileSystemURL( 453 return file_system_context()->CreateCrackedFileSystemURL(
312 dest_root_.origin(), 454 dest_root_.origin(),
313 dest_root_.mount_type(), 455 dest_root_.mount_type(),
314 relative); 456 relative);
315 } 457 }
316 458
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 459 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698