OLD | NEW |
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 "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 #include "webkit/browser/blob/file_stream_reader.h" | 11 #include "webkit/browser/blob/file_stream_reader.h" |
12 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" | 12 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" |
| 13 #include "webkit/browser/fileapi/file_observers.h" |
13 #include "webkit/browser/fileapi/file_stream_writer.h" | 14 #include "webkit/browser/fileapi/file_stream_writer.h" |
14 #include "webkit/browser/fileapi/file_system_context.h" | 15 #include "webkit/browser/fileapi/file_system_context.h" |
15 #include "webkit/browser/fileapi/file_system_operation_runner.h" | 16 #include "webkit/browser/fileapi/file_system_operation_runner.h" |
16 #include "webkit/browser/fileapi/file_system_url.h" | 17 #include "webkit/browser/fileapi/file_system_url.h" |
17 #include "webkit/browser/fileapi/recursive_operation_delegate.h" | 18 #include "webkit/browser/fileapi/recursive_operation_delegate.h" |
18 #include "webkit/common/blob/shareable_file_reference.h" | 19 #include "webkit/common/blob/shareable_file_reference.h" |
19 #include "webkit/common/fileapi/file_system_util.h" | 20 #include "webkit/common/fileapi/file_system_util.h" |
20 | 21 |
21 namespace storage { | 22 namespace storage { |
22 | 23 |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 const int kMinProgressCallbackInvocationSpanInMilliseconds = 50; | 360 const int kMinProgressCallbackInvocationSpanInMilliseconds = 50; |
360 | 361 |
361 // Specifically for cross file system copy/move operation, this class uses | 362 // Specifically for cross file system copy/move operation, this class uses |
362 // stream reader and writer for copying. Validator is not supported, so if | 363 // stream reader and writer for copying. Validator is not supported, so if |
363 // necessary SnapshotCopyOrMoveImpl should be used. | 364 // necessary SnapshotCopyOrMoveImpl should be used. |
364 class StreamCopyOrMoveImpl | 365 class StreamCopyOrMoveImpl |
365 : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { | 366 : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { |
366 public: | 367 public: |
367 StreamCopyOrMoveImpl( | 368 StreamCopyOrMoveImpl( |
368 FileSystemOperationRunner* operation_runner, | 369 FileSystemOperationRunner* operation_runner, |
| 370 FileSystemContext* file_system_context, |
369 CopyOrMoveOperationDelegate::OperationType operation_type, | 371 CopyOrMoveOperationDelegate::OperationType operation_type, |
370 const FileSystemURL& src_url, | 372 const FileSystemURL& src_url, |
371 const FileSystemURL& dest_url, | 373 const FileSystemURL& dest_url, |
372 CopyOrMoveOperationDelegate::CopyOrMoveOption option, | 374 CopyOrMoveOperationDelegate::CopyOrMoveOption option, |
373 scoped_ptr<storage::FileStreamReader> reader, | 375 scoped_ptr<storage::FileStreamReader> reader, |
374 scoped_ptr<FileStreamWriter> writer, | 376 scoped_ptr<FileStreamWriter> writer, |
375 const FileSystemOperation::CopyFileProgressCallback& | 377 const FileSystemOperation::CopyFileProgressCallback& |
376 file_progress_callback) | 378 file_progress_callback) |
377 : operation_runner_(operation_runner), | 379 : operation_runner_(operation_runner), |
| 380 file_system_context_(file_system_context), |
378 operation_type_(operation_type), | 381 operation_type_(operation_type), |
379 src_url_(src_url), | 382 src_url_(src_url), |
380 dest_url_(dest_url), | 383 dest_url_(dest_url), |
381 option_(option), | 384 option_(option), |
382 reader_(reader.Pass()), | 385 reader_(reader.Pass()), |
383 writer_(writer.Pass()), | 386 writer_(writer.Pass()), |
384 file_progress_callback_(file_progress_callback), | 387 file_progress_callback_(file_progress_callback), |
385 cancel_requested_(false), | 388 cancel_requested_(false), |
386 weak_factory_(this) {} | 389 weak_factory_(this) {} |
387 | 390 |
388 virtual void Run( | 391 virtual void Run( |
389 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { | 392 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { |
390 // Reader can be created even if the entry does not exist or the entry is | 393 // Reader can be created even if the entry does not exist or the entry is |
391 // a directory. To check errors before destination file creation, | 394 // a directory. To check errors before destination file creation, |
392 // check metadata first. | 395 // check metadata first. |
393 operation_runner_->GetMetadata( | 396 operation_runner_->GetMetadata( |
394 src_url_, | 397 src_url_, |
395 base::Bind(&StreamCopyOrMoveImpl::RunAfterGetMetadataForSource, | 398 base::Bind(&StreamCopyOrMoveImpl::RunAfterGetMetadataForSource, |
396 weak_factory_.GetWeakPtr(), callback)); | 399 weak_factory_.GetWeakPtr(), callback)); |
397 } | 400 } |
398 | 401 |
399 virtual void Cancel() OVERRIDE { | 402 virtual void Cancel() OVERRIDE { |
400 cancel_requested_ = true; | 403 cancel_requested_ = true; |
401 if (copy_helper_) | 404 if (copy_helper_) |
402 copy_helper_->Cancel(); | 405 copy_helper_->Cancel(); |
403 } | 406 } |
404 | 407 |
405 private: | 408 private: |
| 409 void NotifyOnStartUpdate(const FileSystemURL& url) { |
| 410 if (file_system_context_->GetUpdateObservers(url.type())) { |
| 411 file_system_context_->GetUpdateObservers(url.type()) |
| 412 ->Notify(&FileUpdateObserver::OnStartUpdate, MakeTuple(url)); |
| 413 } |
| 414 } |
| 415 |
| 416 void NotifyOnModifyFile(const FileSystemURL& url) { |
| 417 if (file_system_context_->GetChangeObservers(url.type())) { |
| 418 file_system_context_->GetChangeObservers(url.type()) |
| 419 ->Notify(&FileChangeObserver::OnModifyFile, MakeTuple(url)); |
| 420 } |
| 421 } |
| 422 |
| 423 void NotifyOnEndUpdate(const FileSystemURL& url) { |
| 424 if (file_system_context_->GetUpdateObservers(url.type())) { |
| 425 file_system_context_->GetUpdateObservers(url.type()) |
| 426 ->Notify(&FileUpdateObserver::OnEndUpdate, MakeTuple(url)); |
| 427 } |
| 428 } |
| 429 |
406 void RunAfterGetMetadataForSource( | 430 void RunAfterGetMetadataForSource( |
407 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 431 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
408 base::File::Error error, | 432 base::File::Error error, |
409 const base::File::Info& file_info) { | 433 const base::File::Info& file_info) { |
410 if (cancel_requested_) | 434 if (cancel_requested_) |
411 error = base::File::FILE_ERROR_ABORT; | 435 error = base::File::FILE_ERROR_ABORT; |
412 | 436 |
413 if (error != base::File::FILE_OK) { | 437 if (error != base::File::FILE_OK) { |
414 callback.Run(error); | 438 callback.Run(error); |
415 return; | 439 return; |
(...skipping 14 matching lines...) Expand all Loading... |
430 callback, | 454 callback, |
431 file_info.last_modified)); | 455 file_info.last_modified)); |
432 } | 456 } |
433 | 457 |
434 void RunAfterCreateFileForDestination( | 458 void RunAfterCreateFileForDestination( |
435 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 459 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
436 const base::Time& last_modified, | 460 const base::Time& last_modified, |
437 base::File::Error error) { | 461 base::File::Error error) { |
438 if (cancel_requested_) | 462 if (cancel_requested_) |
439 error = base::File::FILE_ERROR_ABORT; | 463 error = base::File::FILE_ERROR_ABORT; |
| 464 // This conversion is to return the consistent status code with |
| 465 // FileSystemFileUtil::Copy. |
| 466 if (error == base::File::FILE_ERROR_NOT_A_FILE) |
| 467 error = base::File::FILE_ERROR_INVALID_OPERATION; |
440 | 468 |
441 if (error != base::File::FILE_OK && | 469 if (error != base::File::FILE_OK && |
442 error != base::File::FILE_ERROR_EXISTS) { | 470 error != base::File::FILE_ERROR_EXISTS) { |
443 callback.Run(error); | 471 callback.Run(error); |
444 return; | 472 return; |
445 } | 473 } |
446 | 474 |
447 if (error == base::File::FILE_ERROR_EXISTS) { | 475 if (error == base::File::FILE_ERROR_EXISTS) { |
448 operation_runner_->Truncate( | 476 operation_runner_->Truncate( |
449 dest_url_, | 477 dest_url_, |
(...skipping 16 matching lines...) Expand all Loading... |
466 error = base::File::FILE_ERROR_ABORT; | 494 error = base::File::FILE_ERROR_ABORT; |
467 | 495 |
468 if (error != base::File::FILE_OK) { | 496 if (error != base::File::FILE_OK) { |
469 callback.Run(error); | 497 callback.Run(error); |
470 return; | 498 return; |
471 } | 499 } |
472 | 500 |
473 const bool need_flush = dest_url_.mount_option().copy_sync_option() == | 501 const bool need_flush = dest_url_.mount_option().copy_sync_option() == |
474 storage::COPY_SYNC_OPTION_SYNC; | 502 storage::COPY_SYNC_OPTION_SYNC; |
475 | 503 |
| 504 NotifyOnStartUpdate(dest_url_); |
476 DCHECK(!copy_helper_); | 505 DCHECK(!copy_helper_); |
477 copy_helper_.reset( | 506 copy_helper_.reset( |
478 new CopyOrMoveOperationDelegate::StreamCopyHelper( | 507 new CopyOrMoveOperationDelegate::StreamCopyHelper( |
479 reader_.Pass(), writer_.Pass(), | 508 reader_.Pass(), writer_.Pass(), |
480 need_flush, | 509 need_flush, |
481 kReadBufferSize, | 510 kReadBufferSize, |
482 file_progress_callback_, | 511 file_progress_callback_, |
483 base::TimeDelta::FromMilliseconds( | 512 base::TimeDelta::FromMilliseconds( |
484 kMinProgressCallbackInvocationSpanInMilliseconds))); | 513 kMinProgressCallbackInvocationSpanInMilliseconds))); |
485 copy_helper_->Run( | 514 copy_helper_->Run( |
486 base::Bind(&StreamCopyOrMoveImpl::RunAfterStreamCopy, | 515 base::Bind(&StreamCopyOrMoveImpl::RunAfterStreamCopy, |
487 weak_factory_.GetWeakPtr(), callback, last_modified)); | 516 weak_factory_.GetWeakPtr(), callback, last_modified)); |
488 } | 517 } |
489 | 518 |
490 void RunAfterStreamCopy( | 519 void RunAfterStreamCopy( |
491 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 520 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
492 const base::Time& last_modified, | 521 const base::Time& last_modified, |
493 base::File::Error error) { | 522 base::File::Error error) { |
| 523 NotifyOnModifyFile(dest_url_); |
| 524 NotifyOnEndUpdate(dest_url_); |
494 if (cancel_requested_) | 525 if (cancel_requested_) |
495 error = base::File::FILE_ERROR_ABORT; | 526 error = base::File::FILE_ERROR_ABORT; |
496 | 527 |
497 if (error != base::File::FILE_OK) { | 528 if (error != base::File::FILE_OK) { |
498 callback.Run(error); | 529 callback.Run(error); |
499 return; | 530 return; |
500 } | 531 } |
501 | 532 |
502 if (option_ == FileSystemOperation::OPTION_NONE) { | 533 if (option_ == FileSystemOperation::OPTION_NONE) { |
503 RunAfterTouchFile(callback, base::File::FILE_OK); | 534 RunAfterTouchFile(callback, base::File::FILE_OK); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 568 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
538 base::File::Error error) { | 569 base::File::Error error) { |
539 if (cancel_requested_) | 570 if (cancel_requested_) |
540 error = base::File::FILE_ERROR_ABORT; | 571 error = base::File::FILE_ERROR_ABORT; |
541 if (error == base::File::FILE_ERROR_NOT_FOUND) | 572 if (error == base::File::FILE_ERROR_NOT_FOUND) |
542 error = base::File::FILE_OK; | 573 error = base::File::FILE_OK; |
543 callback.Run(error); | 574 callback.Run(error); |
544 } | 575 } |
545 | 576 |
546 FileSystemOperationRunner* operation_runner_; | 577 FileSystemOperationRunner* operation_runner_; |
| 578 scoped_refptr<FileSystemContext> file_system_context_; |
547 CopyOrMoveOperationDelegate::OperationType operation_type_; | 579 CopyOrMoveOperationDelegate::OperationType operation_type_; |
548 FileSystemURL src_url_; | 580 FileSystemURL src_url_; |
549 FileSystemURL dest_url_; | 581 FileSystemURL dest_url_; |
550 CopyOrMoveOperationDelegate::CopyOrMoveOption option_; | 582 CopyOrMoveOperationDelegate::CopyOrMoveOption option_; |
551 scoped_ptr<storage::FileStreamReader> reader_; | 583 scoped_ptr<storage::FileStreamReader> reader_; |
552 scoped_ptr<FileStreamWriter> writer_; | 584 scoped_ptr<FileStreamWriter> writer_; |
553 FileSystemOperation::CopyFileProgressCallback file_progress_callback_; | 585 FileSystemOperation::CopyFileProgressCallback file_progress_callback_; |
554 scoped_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; | 586 scoped_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; |
555 bool cancel_requested_; | 587 bool cancel_requested_; |
556 base::WeakPtrFactory<StreamCopyOrMoveImpl> weak_factory_; | 588 base::WeakPtrFactory<StreamCopyOrMoveImpl> weak_factory_; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 } | 816 } |
785 | 817 |
786 if (!validator_factory) { | 818 if (!validator_factory) { |
787 scoped_ptr<storage::FileStreamReader> reader = | 819 scoped_ptr<storage::FileStreamReader> reader = |
788 file_system_context()->CreateFileStreamReader( | 820 file_system_context()->CreateFileStreamReader( |
789 src_url, 0, base::Time()); | 821 src_url, 0, base::Time()); |
790 scoped_ptr<FileStreamWriter> writer = | 822 scoped_ptr<FileStreamWriter> writer = |
791 file_system_context()->CreateFileStreamWriter(dest_url, 0); | 823 file_system_context()->CreateFileStreamWriter(dest_url, 0); |
792 if (reader && writer) { | 824 if (reader && writer) { |
793 impl = new StreamCopyOrMoveImpl( | 825 impl = new StreamCopyOrMoveImpl( |
794 operation_runner(), operation_type_, src_url, dest_url, option_, | 826 operation_runner(), |
795 reader.Pass(), writer.Pass(), | 827 file_system_context(), |
| 828 operation_type_, |
| 829 src_url, |
| 830 dest_url, |
| 831 option_, |
| 832 reader.Pass(), |
| 833 writer.Pass(), |
796 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, | 834 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, |
797 weak_factory_.GetWeakPtr(), src_url)); | 835 weak_factory_.GetWeakPtr(), |
| 836 src_url)); |
798 } | 837 } |
799 } | 838 } |
800 | 839 |
801 if (!impl) { | 840 if (!impl) { |
802 impl = new SnapshotCopyOrMoveImpl( | 841 impl = new SnapshotCopyOrMoveImpl( |
803 operation_runner(), operation_type_, src_url, dest_url, option_, | 842 operation_runner(), operation_type_, src_url, dest_url, option_, |
804 validator_factory, | 843 validator_factory, |
805 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, | 844 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, |
806 weak_factory_.GetWeakPtr(), src_url)); | 845 weak_factory_.GetWeakPtr(), src_url)); |
807 } | 846 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 base::FilePath relative = dest_root_.virtual_path(); | 1025 base::FilePath relative = dest_root_.virtual_path(); |
987 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), | 1026 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), |
988 &relative); | 1027 &relative); |
989 return file_system_context()->CreateCrackedFileSystemURL( | 1028 return file_system_context()->CreateCrackedFileSystemURL( |
990 dest_root_.origin(), | 1029 dest_root_.origin(), |
991 dest_root_.mount_type(), | 1030 dest_root_.mount_type(), |
992 relative); | 1031 relative); |
993 } | 1032 } |
994 | 1033 |
995 } // namespace storage | 1034 } // namespace storage |
OLD | NEW |