OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "webkit/browser/fileapi/file_system_operation_runner.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/message_loop/message_loop_proxy.h" | |
9 #include "base/stl_util.h" | |
10 #include "net/url_request/url_request_context.h" | |
11 #include "webkit/browser/blob/blob_url_request_job_factory.h" | |
12 #include "webkit/browser/fileapi/file_observers.h" | |
13 #include "webkit/browser/fileapi/file_stream_writer.h" | |
14 #include "webkit/browser/fileapi/file_system_context.h" | |
15 #include "webkit/browser/fileapi/file_system_operation.h" | |
16 #include "webkit/browser/fileapi/file_writer_delegate.h" | |
17 #include "webkit/common/blob/shareable_file_reference.h" | |
18 | |
19 namespace fileapi { | |
20 | |
21 typedef FileSystemOperationRunner::OperationID OperationID; | |
22 | |
23 class FileSystemOperationRunner::BeginOperationScoper | |
24 : public base::SupportsWeakPtr< | |
25 FileSystemOperationRunner::BeginOperationScoper> { | |
26 public: | |
27 BeginOperationScoper() {} | |
28 private: | |
29 DISALLOW_COPY_AND_ASSIGN(BeginOperationScoper); | |
30 }; | |
31 | |
32 FileSystemOperationRunner::OperationHandle::OperationHandle() {} | |
33 FileSystemOperationRunner::OperationHandle::~OperationHandle() {} | |
34 | |
35 FileSystemOperationRunner::~FileSystemOperationRunner() { | |
36 } | |
37 | |
38 void FileSystemOperationRunner::Shutdown() { | |
39 operations_.Clear(); | |
40 } | |
41 | |
42 OperationID FileSystemOperationRunner::CreateFile( | |
43 const FileSystemURL& url, | |
44 bool exclusive, | |
45 const StatusCallback& callback) { | |
46 base::File::Error error = base::File::FILE_OK; | |
47 FileSystemOperation* operation = | |
48 file_system_context_->CreateFileSystemOperation(url, &error); | |
49 | |
50 BeginOperationScoper scope; | |
51 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
52 if (!operation) { | |
53 DidFinish(handle, callback, error); | |
54 return handle.id; | |
55 } | |
56 PrepareForWrite(handle.id, url); | |
57 operation->CreateFile( | |
58 url, exclusive, | |
59 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
60 handle, callback)); | |
61 return handle.id; | |
62 } | |
63 | |
64 OperationID FileSystemOperationRunner::CreateDirectory( | |
65 const FileSystemURL& url, | |
66 bool exclusive, | |
67 bool recursive, | |
68 const StatusCallback& callback) { | |
69 base::File::Error error = base::File::FILE_OK; | |
70 FileSystemOperation* operation = | |
71 file_system_context_->CreateFileSystemOperation(url, &error); | |
72 BeginOperationScoper scope; | |
73 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
74 if (!operation) { | |
75 DidFinish(handle, callback, error); | |
76 return handle.id; | |
77 } | |
78 PrepareForWrite(handle.id, url); | |
79 operation->CreateDirectory( | |
80 url, exclusive, recursive, | |
81 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
82 handle, callback)); | |
83 return handle.id; | |
84 } | |
85 | |
86 OperationID FileSystemOperationRunner::Copy( | |
87 const FileSystemURL& src_url, | |
88 const FileSystemURL& dest_url, | |
89 CopyOrMoveOption option, | |
90 const CopyProgressCallback& progress_callback, | |
91 const StatusCallback& callback) { | |
92 base::File::Error error = base::File::FILE_OK; | |
93 FileSystemOperation* operation = | |
94 file_system_context_->CreateFileSystemOperation(dest_url, &error); | |
95 BeginOperationScoper scope; | |
96 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
97 if (!operation) { | |
98 DidFinish(handle, callback, error); | |
99 return handle.id; | |
100 } | |
101 PrepareForWrite(handle.id, dest_url); | |
102 PrepareForRead(handle.id, src_url); | |
103 operation->Copy( | |
104 src_url, dest_url, option, | |
105 progress_callback.is_null() ? | |
106 CopyProgressCallback() : | |
107 base::Bind(&FileSystemOperationRunner::OnCopyProgress, AsWeakPtr(), | |
108 handle, progress_callback), | |
109 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
110 handle, callback)); | |
111 return handle.id; | |
112 } | |
113 | |
114 OperationID FileSystemOperationRunner::Move( | |
115 const FileSystemURL& src_url, | |
116 const FileSystemURL& dest_url, | |
117 CopyOrMoveOption option, | |
118 const StatusCallback& callback) { | |
119 base::File::Error error = base::File::FILE_OK; | |
120 FileSystemOperation* operation = | |
121 file_system_context_->CreateFileSystemOperation(dest_url, &error); | |
122 BeginOperationScoper scope; | |
123 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
124 if (!operation) { | |
125 DidFinish(handle, callback, error); | |
126 return handle.id; | |
127 } | |
128 PrepareForWrite(handle.id, dest_url); | |
129 PrepareForWrite(handle.id, src_url); | |
130 operation->Move( | |
131 src_url, dest_url, option, | |
132 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
133 handle, callback)); | |
134 return handle.id; | |
135 } | |
136 | |
137 OperationID FileSystemOperationRunner::DirectoryExists( | |
138 const FileSystemURL& url, | |
139 const StatusCallback& callback) { | |
140 base::File::Error error = base::File::FILE_OK; | |
141 FileSystemOperation* operation = | |
142 file_system_context_->CreateFileSystemOperation(url, &error); | |
143 BeginOperationScoper scope; | |
144 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
145 if (!operation) { | |
146 DidFinish(handle, callback, error); | |
147 return handle.id; | |
148 } | |
149 PrepareForRead(handle.id, url); | |
150 operation->DirectoryExists( | |
151 url, | |
152 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
153 handle, callback)); | |
154 return handle.id; | |
155 } | |
156 | |
157 OperationID FileSystemOperationRunner::FileExists( | |
158 const FileSystemURL& url, | |
159 const StatusCallback& callback) { | |
160 base::File::Error error = base::File::FILE_OK; | |
161 FileSystemOperation* operation = | |
162 file_system_context_->CreateFileSystemOperation(url, &error); | |
163 BeginOperationScoper scope; | |
164 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
165 if (!operation) { | |
166 DidFinish(handle, callback, error); | |
167 return handle.id; | |
168 } | |
169 PrepareForRead(handle.id, url); | |
170 operation->FileExists( | |
171 url, | |
172 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
173 handle, callback)); | |
174 return handle.id; | |
175 } | |
176 | |
177 OperationID FileSystemOperationRunner::GetMetadata( | |
178 const FileSystemURL& url, | |
179 const GetMetadataCallback& callback) { | |
180 base::File::Error error = base::File::FILE_OK; | |
181 FileSystemOperation* operation = | |
182 file_system_context_->CreateFileSystemOperation(url, &error); | |
183 BeginOperationScoper scope; | |
184 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
185 if (!operation) { | |
186 DidGetMetadata(handle, callback, error, base::File::Info()); | |
187 return handle.id; | |
188 } | |
189 PrepareForRead(handle.id, url); | |
190 operation->GetMetadata( | |
191 url, | |
192 base::Bind(&FileSystemOperationRunner::DidGetMetadata, AsWeakPtr(), | |
193 handle, callback)); | |
194 return handle.id; | |
195 } | |
196 | |
197 OperationID FileSystemOperationRunner::ReadDirectory( | |
198 const FileSystemURL& url, | |
199 const ReadDirectoryCallback& callback) { | |
200 base::File::Error error = base::File::FILE_OK; | |
201 FileSystemOperation* operation = | |
202 file_system_context_->CreateFileSystemOperation(url, &error); | |
203 BeginOperationScoper scope; | |
204 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
205 if (!operation) { | |
206 DidReadDirectory(handle, callback, error, std::vector<DirectoryEntry>(), | |
207 false); | |
208 return handle.id; | |
209 } | |
210 PrepareForRead(handle.id, url); | |
211 operation->ReadDirectory( | |
212 url, | |
213 base::Bind(&FileSystemOperationRunner::DidReadDirectory, AsWeakPtr(), | |
214 handle, callback)); | |
215 return handle.id; | |
216 } | |
217 | |
218 OperationID FileSystemOperationRunner::Remove( | |
219 const FileSystemURL& url, bool recursive, | |
220 const StatusCallback& callback) { | |
221 base::File::Error error = base::File::FILE_OK; | |
222 FileSystemOperation* operation = | |
223 file_system_context_->CreateFileSystemOperation(url, &error); | |
224 BeginOperationScoper scope; | |
225 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
226 if (!operation) { | |
227 DidFinish(handle, callback, error); | |
228 return handle.id; | |
229 } | |
230 PrepareForWrite(handle.id, url); | |
231 operation->Remove( | |
232 url, recursive, | |
233 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
234 handle, callback)); | |
235 return handle.id; | |
236 } | |
237 | |
238 OperationID FileSystemOperationRunner::Write( | |
239 const net::URLRequestContext* url_request_context, | |
240 const FileSystemURL& url, | |
241 scoped_ptr<webkit_blob::BlobDataHandle> blob, | |
242 int64 offset, | |
243 const WriteCallback& callback) { | |
244 base::File::Error error = base::File::FILE_OK; | |
245 FileSystemOperation* operation = | |
246 file_system_context_->CreateFileSystemOperation(url, &error); | |
247 | |
248 BeginOperationScoper scope; | |
249 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
250 if (!operation) { | |
251 DidWrite(handle, callback, error, 0, true); | |
252 return handle.id; | |
253 } | |
254 | |
255 scoped_ptr<FileStreamWriter> writer( | |
256 file_system_context_->CreateFileStreamWriter(url, offset)); | |
257 if (!writer) { | |
258 // Write is not supported. | |
259 DidWrite(handle, callback, base::File::FILE_ERROR_SECURITY, 0, true); | |
260 return handle.id; | |
261 } | |
262 | |
263 FileWriterDelegate::FlushPolicy flush_policy = | |
264 file_system_context_->ShouldFlushOnWriteCompletion(url.type()) | |
265 ? FileWriterDelegate::FLUSH_ON_COMPLETION | |
266 : FileWriterDelegate::NO_FLUSH_ON_COMPLETION; | |
267 scoped_ptr<FileWriterDelegate> writer_delegate( | |
268 new FileWriterDelegate(writer.Pass(), flush_policy)); | |
269 | |
270 scoped_ptr<net::URLRequest> blob_request( | |
271 webkit_blob::BlobProtocolHandler::CreateBlobRequest( | |
272 blob.Pass(), | |
273 url_request_context, | |
274 writer_delegate.get())); | |
275 | |
276 PrepareForWrite(handle.id, url); | |
277 operation->Write( | |
278 url, writer_delegate.Pass(), blob_request.Pass(), | |
279 base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), | |
280 handle, callback)); | |
281 return handle.id; | |
282 } | |
283 | |
284 OperationID FileSystemOperationRunner::Truncate( | |
285 const FileSystemURL& url, int64 length, | |
286 const StatusCallback& callback) { | |
287 base::File::Error error = base::File::FILE_OK; | |
288 FileSystemOperation* operation = | |
289 file_system_context_->CreateFileSystemOperation(url, &error); | |
290 BeginOperationScoper scope; | |
291 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
292 if (!operation) { | |
293 DidFinish(handle, callback, error); | |
294 return handle.id; | |
295 } | |
296 PrepareForWrite(handle.id, url); | |
297 operation->Truncate( | |
298 url, length, | |
299 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
300 handle, callback)); | |
301 return handle.id; | |
302 } | |
303 | |
304 void FileSystemOperationRunner::Cancel( | |
305 OperationID id, | |
306 const StatusCallback& callback) { | |
307 if (ContainsKey(finished_operations_, id)) { | |
308 DCHECK(!ContainsKey(stray_cancel_callbacks_, id)); | |
309 stray_cancel_callbacks_[id] = callback; | |
310 return; | |
311 } | |
312 FileSystemOperation* operation = operations_.Lookup(id); | |
313 if (!operation) { | |
314 // There is no operation with |id|. | |
315 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION); | |
316 return; | |
317 } | |
318 operation->Cancel(callback); | |
319 } | |
320 | |
321 OperationID FileSystemOperationRunner::TouchFile( | |
322 const FileSystemURL& url, | |
323 const base::Time& last_access_time, | |
324 const base::Time& last_modified_time, | |
325 const StatusCallback& callback) { | |
326 base::File::Error error = base::File::FILE_OK; | |
327 FileSystemOperation* operation = | |
328 file_system_context_->CreateFileSystemOperation(url, &error); | |
329 BeginOperationScoper scope; | |
330 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
331 if (!operation) { | |
332 DidFinish(handle, callback, error); | |
333 return handle.id; | |
334 } | |
335 PrepareForWrite(handle.id, url); | |
336 operation->TouchFile( | |
337 url, last_access_time, last_modified_time, | |
338 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
339 handle, callback)); | |
340 return handle.id; | |
341 } | |
342 | |
343 OperationID FileSystemOperationRunner::OpenFile( | |
344 const FileSystemURL& url, | |
345 int file_flags, | |
346 const OpenFileCallback& callback) { | |
347 base::File::Error error = base::File::FILE_OK; | |
348 FileSystemOperation* operation = | |
349 file_system_context_->CreateFileSystemOperation(url, &error); | |
350 BeginOperationScoper scope; | |
351 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
352 if (!operation) { | |
353 DidOpenFile(handle, callback, base::File(error), base::Closure()); | |
354 return handle.id; | |
355 } | |
356 if (file_flags & | |
357 (base::File::FLAG_CREATE | base::File::FLAG_OPEN_ALWAYS | | |
358 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_OPEN_TRUNCATED | | |
359 base::File::FLAG_WRITE | base::File::FLAG_EXCLUSIVE_WRITE | | |
360 base::File::FLAG_DELETE_ON_CLOSE | | |
361 base::File::FLAG_WRITE_ATTRIBUTES)) { | |
362 PrepareForWrite(handle.id, url); | |
363 } else { | |
364 PrepareForRead(handle.id, url); | |
365 } | |
366 operation->OpenFile( | |
367 url, file_flags, | |
368 base::Bind(&FileSystemOperationRunner::DidOpenFile, AsWeakPtr(), | |
369 handle, callback)); | |
370 return handle.id; | |
371 } | |
372 | |
373 OperationID FileSystemOperationRunner::CreateSnapshotFile( | |
374 const FileSystemURL& url, | |
375 const SnapshotFileCallback& callback) { | |
376 base::File::Error error = base::File::FILE_OK; | |
377 FileSystemOperation* operation = | |
378 file_system_context_->CreateFileSystemOperation(url, &error); | |
379 BeginOperationScoper scope; | |
380 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
381 if (!operation) { | |
382 DidCreateSnapshot(handle, callback, error, base::File::Info(), | |
383 base::FilePath(), NULL); | |
384 return handle.id; | |
385 } | |
386 PrepareForRead(handle.id, url); | |
387 operation->CreateSnapshotFile( | |
388 url, | |
389 base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, AsWeakPtr(), | |
390 handle, callback)); | |
391 return handle.id; | |
392 } | |
393 | |
394 OperationID FileSystemOperationRunner::CopyInForeignFile( | |
395 const base::FilePath& src_local_disk_path, | |
396 const FileSystemURL& dest_url, | |
397 const StatusCallback& callback) { | |
398 base::File::Error error = base::File::FILE_OK; | |
399 FileSystemOperation* operation = | |
400 file_system_context_->CreateFileSystemOperation(dest_url, &error); | |
401 BeginOperationScoper scope; | |
402 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
403 if (!operation) { | |
404 DidFinish(handle, callback, error); | |
405 return handle.id; | |
406 } | |
407 operation->CopyInForeignFile( | |
408 src_local_disk_path, dest_url, | |
409 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
410 handle, callback)); | |
411 return handle.id; | |
412 } | |
413 | |
414 OperationID FileSystemOperationRunner::RemoveFile( | |
415 const FileSystemURL& url, | |
416 const StatusCallback& callback) { | |
417 base::File::Error error = base::File::FILE_OK; | |
418 FileSystemOperation* operation = | |
419 file_system_context_->CreateFileSystemOperation(url, &error); | |
420 BeginOperationScoper scope; | |
421 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
422 if (!operation) { | |
423 DidFinish(handle, callback, error); | |
424 return handle.id; | |
425 } | |
426 operation->RemoveFile( | |
427 url, | |
428 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
429 handle, callback)); | |
430 return handle.id; | |
431 } | |
432 | |
433 OperationID FileSystemOperationRunner::RemoveDirectory( | |
434 const FileSystemURL& url, | |
435 const StatusCallback& callback) { | |
436 base::File::Error error = base::File::FILE_OK; | |
437 FileSystemOperation* operation = | |
438 file_system_context_->CreateFileSystemOperation(url, &error); | |
439 BeginOperationScoper scope; | |
440 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
441 if (!operation) { | |
442 DidFinish(handle, callback, error); | |
443 return handle.id; | |
444 } | |
445 operation->RemoveDirectory( | |
446 url, | |
447 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
448 handle, callback)); | |
449 return handle.id; | |
450 } | |
451 | |
452 OperationID FileSystemOperationRunner::CopyFileLocal( | |
453 const FileSystemURL& src_url, | |
454 const FileSystemURL& dest_url, | |
455 CopyOrMoveOption option, | |
456 const CopyFileProgressCallback& progress_callback, | |
457 const StatusCallback& callback) { | |
458 base::File::Error error = base::File::FILE_OK; | |
459 FileSystemOperation* operation = | |
460 file_system_context_->CreateFileSystemOperation(src_url, &error); | |
461 BeginOperationScoper scope; | |
462 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
463 if (!operation) { | |
464 DidFinish(handle, callback, error); | |
465 return handle.id; | |
466 } | |
467 operation->CopyFileLocal( | |
468 src_url, dest_url, option, progress_callback, | |
469 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
470 handle, callback)); | |
471 return handle.id; | |
472 } | |
473 | |
474 OperationID FileSystemOperationRunner::MoveFileLocal( | |
475 const FileSystemURL& src_url, | |
476 const FileSystemURL& dest_url, | |
477 CopyOrMoveOption option, | |
478 const StatusCallback& callback) { | |
479 base::File::Error error = base::File::FILE_OK; | |
480 FileSystemOperation* operation = | |
481 file_system_context_->CreateFileSystemOperation(src_url, &error); | |
482 BeginOperationScoper scope; | |
483 OperationHandle handle = BeginOperation(operation, scope.AsWeakPtr()); | |
484 if (!operation) { | |
485 DidFinish(handle, callback, error); | |
486 return handle.id; | |
487 } | |
488 operation->MoveFileLocal( | |
489 src_url, dest_url, option, | |
490 base::Bind(&FileSystemOperationRunner::DidFinish, AsWeakPtr(), | |
491 handle, callback)); | |
492 return handle.id; | |
493 } | |
494 | |
495 base::File::Error FileSystemOperationRunner::SyncGetPlatformPath( | |
496 const FileSystemURL& url, | |
497 base::FilePath* platform_path) { | |
498 base::File::Error error = base::File::FILE_OK; | |
499 scoped_ptr<FileSystemOperation> operation( | |
500 file_system_context_->CreateFileSystemOperation(url, &error)); | |
501 if (!operation.get()) | |
502 return error; | |
503 return operation->SyncGetPlatformPath(url, platform_path); | |
504 } | |
505 | |
506 FileSystemOperationRunner::FileSystemOperationRunner( | |
507 FileSystemContext* file_system_context) | |
508 : file_system_context_(file_system_context) {} | |
509 | |
510 void FileSystemOperationRunner::DidFinish( | |
511 const OperationHandle& handle, | |
512 const StatusCallback& callback, | |
513 base::File::Error rv) { | |
514 if (handle.scope) { | |
515 finished_operations_.insert(handle.id); | |
516 base::MessageLoopProxy::current()->PostTask( | |
517 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidFinish, | |
518 AsWeakPtr(), handle, callback, rv)); | |
519 return; | |
520 } | |
521 callback.Run(rv); | |
522 FinishOperation(handle.id); | |
523 } | |
524 | |
525 void FileSystemOperationRunner::DidGetMetadata( | |
526 const OperationHandle& handle, | |
527 const GetMetadataCallback& callback, | |
528 base::File::Error rv, | |
529 const base::File::Info& file_info) { | |
530 if (handle.scope) { | |
531 finished_operations_.insert(handle.id); | |
532 base::MessageLoopProxy::current()->PostTask( | |
533 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidGetMetadata, | |
534 AsWeakPtr(), handle, callback, rv, file_info)); | |
535 return; | |
536 } | |
537 callback.Run(rv, file_info); | |
538 FinishOperation(handle.id); | |
539 } | |
540 | |
541 void FileSystemOperationRunner::DidReadDirectory( | |
542 const OperationHandle& handle, | |
543 const ReadDirectoryCallback& callback, | |
544 base::File::Error rv, | |
545 const std::vector<DirectoryEntry>& entries, | |
546 bool has_more) { | |
547 if (handle.scope) { | |
548 finished_operations_.insert(handle.id); | |
549 base::MessageLoopProxy::current()->PostTask( | |
550 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidReadDirectory, | |
551 AsWeakPtr(), handle, callback, rv, | |
552 entries, has_more)); | |
553 return; | |
554 } | |
555 callback.Run(rv, entries, has_more); | |
556 if (rv != base::File::FILE_OK || !has_more) | |
557 FinishOperation(handle.id); | |
558 } | |
559 | |
560 void FileSystemOperationRunner::DidWrite( | |
561 const OperationHandle& handle, | |
562 const WriteCallback& callback, | |
563 base::File::Error rv, | |
564 int64 bytes, | |
565 bool complete) { | |
566 if (handle.scope) { | |
567 finished_operations_.insert(handle.id); | |
568 base::MessageLoopProxy::current()->PostTask( | |
569 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidWrite, AsWeakPtr(), | |
570 handle, callback, rv, bytes, complete)); | |
571 return; | |
572 } | |
573 callback.Run(rv, bytes, complete); | |
574 if (rv != base::File::FILE_OK || complete) | |
575 FinishOperation(handle.id); | |
576 } | |
577 | |
578 void FileSystemOperationRunner::DidOpenFile( | |
579 const OperationHandle& handle, | |
580 const OpenFileCallback& callback, | |
581 base::File file, | |
582 const base::Closure& on_close_callback) { | |
583 if (handle.scope) { | |
584 finished_operations_.insert(handle.id); | |
585 base::MessageLoopProxy::current()->PostTask( | |
586 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidOpenFile, | |
587 AsWeakPtr(), handle, callback, Passed(&file), | |
588 on_close_callback)); | |
589 return; | |
590 } | |
591 callback.Run(file.Pass(), on_close_callback); | |
592 FinishOperation(handle.id); | |
593 } | |
594 | |
595 void FileSystemOperationRunner::DidCreateSnapshot( | |
596 const OperationHandle& handle, | |
597 const SnapshotFileCallback& callback, | |
598 base::File::Error rv, | |
599 const base::File::Info& file_info, | |
600 const base::FilePath& platform_path, | |
601 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { | |
602 if (handle.scope) { | |
603 finished_operations_.insert(handle.id); | |
604 base::MessageLoopProxy::current()->PostTask( | |
605 FROM_HERE, base::Bind(&FileSystemOperationRunner::DidCreateSnapshot, | |
606 AsWeakPtr(), handle, callback, rv, file_info, | |
607 platform_path, file_ref)); | |
608 return; | |
609 } | |
610 callback.Run(rv, file_info, platform_path, file_ref); | |
611 FinishOperation(handle.id); | |
612 } | |
613 | |
614 void FileSystemOperationRunner::OnCopyProgress( | |
615 const OperationHandle& handle, | |
616 const CopyProgressCallback& callback, | |
617 FileSystemOperation::CopyProgressType type, | |
618 const FileSystemURL& source_url, | |
619 const FileSystemURL& dest_url, | |
620 int64 size) { | |
621 if (handle.scope) { | |
622 base::MessageLoopProxy::current()->PostTask( | |
623 FROM_HERE, base::Bind( | |
624 &FileSystemOperationRunner::OnCopyProgress, | |
625 AsWeakPtr(), handle, callback, type, source_url, dest_url, size)); | |
626 return; | |
627 } | |
628 callback.Run(type, source_url, dest_url, size); | |
629 } | |
630 | |
631 void FileSystemOperationRunner::PrepareForWrite(OperationID id, | |
632 const FileSystemURL& url) { | |
633 if (file_system_context_->GetUpdateObservers(url.type())) { | |
634 file_system_context_->GetUpdateObservers(url.type())->Notify( | |
635 &FileUpdateObserver::OnStartUpdate, MakeTuple(url)); | |
636 } | |
637 write_target_urls_[id].insert(url); | |
638 } | |
639 | |
640 void FileSystemOperationRunner::PrepareForRead(OperationID id, | |
641 const FileSystemURL& url) { | |
642 if (file_system_context_->GetAccessObservers(url.type())) { | |
643 file_system_context_->GetAccessObservers(url.type())->Notify( | |
644 &FileAccessObserver::OnAccess, MakeTuple(url)); | |
645 } | |
646 } | |
647 | |
648 FileSystemOperationRunner::OperationHandle | |
649 FileSystemOperationRunner::BeginOperation( | |
650 FileSystemOperation* operation, | |
651 base::WeakPtr<BeginOperationScoper> scope) { | |
652 OperationHandle handle; | |
653 handle.id = operations_.Add(operation); | |
654 handle.scope = scope; | |
655 return handle; | |
656 } | |
657 | |
658 void FileSystemOperationRunner::FinishOperation(OperationID id) { | |
659 OperationToURLSet::iterator found = write_target_urls_.find(id); | |
660 if (found != write_target_urls_.end()) { | |
661 const FileSystemURLSet& urls = found->second; | |
662 for (FileSystemURLSet::const_iterator iter = urls.begin(); | |
663 iter != urls.end(); ++iter) { | |
664 if (file_system_context_->GetUpdateObservers(iter->type())) { | |
665 file_system_context_->GetUpdateObservers(iter->type())->Notify( | |
666 &FileUpdateObserver::OnEndUpdate, MakeTuple(*iter)); | |
667 } | |
668 } | |
669 write_target_urls_.erase(found); | |
670 } | |
671 | |
672 // IDMap::Lookup fails if the operation is NULL, so we don't check | |
673 // operations_.Lookup(id) here. | |
674 | |
675 operations_.Remove(id); | |
676 finished_operations_.erase(id); | |
677 | |
678 // Dispatch stray cancel callback if exists. | |
679 std::map<OperationID, StatusCallback>::iterator found_cancel = | |
680 stray_cancel_callbacks_.find(id); | |
681 if (found_cancel != stray_cancel_callbacks_.end()) { | |
682 // This cancel has been requested after the operation has finished, | |
683 // so report that we failed to stop it. | |
684 found_cancel->second.Run(base::File::FILE_ERROR_INVALID_OPERATION); | |
685 stray_cancel_callbacks_.erase(found_cancel); | |
686 } | |
687 } | |
688 | |
689 } // namespace fileapi | |
OLD | NEW |