12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/copy_or_move_operation_delegate.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h" 968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/base/io_buffer.h" 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/base/net_errors.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/copy_or_move_file_validator.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_observers.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_stream_writer.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/recursive_operation_delegate.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/blob/shareable_file_reference.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int64 kFlushIntervalInBytes = 10 << 20; // 10MB. 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class CopyOrMoveOperationDelegate::CopyOrMoveImpl { 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~CopyOrMoveImpl() {} 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void Run( 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback) = 0; 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Cancel() = 0; 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected: 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CopyOrMoveImpl() {} 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CopyOrMoveImpl); 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace { 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copies a file on a (same) file system. Just delegate the operation to 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// |operation_runner|. 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class CopyOrMoveOnSameFileSystemImpl 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CopyOrMoveOnSameFileSystemImpl( 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner* operation_runner, 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CopyOrMoveOperationDelegate::OperationType operation_type, 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const FileSystemURL& src_url, 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& dest_url, 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOperationDelegate::CopyOrMoveOption option, 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemOperation::CopyFileProgressCallback& 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_progress_callback) 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : operation_runner_(operation_runner), 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_type_(operation_type), 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) src_url_(src_url), 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dest_url_(dest_url), 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) option_(option), 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_progress_callback_(file_progress_callback) { 6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void Run( 6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { 6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_MOVE) { 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) operation_runner_->MoveFileLocal(src_url_, dest_url_, option_, callback); 6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner_->CopyFileLocal( 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) src_url_, dest_url_, option_, file_progress_callback_, callback); 7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Cancel() OVERRIDE { 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We can do nothing for the copy/move operation on a local file system. 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Assuming the operation is quickly done, it should be ok to just wait 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // for the completion. 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner* operation_runner_; 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CopyOrMoveOperationDelegate::OperationType operation_type_; 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemURL src_url_; 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemURL dest_url_; 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOperationDelegate::CopyOrMoveOption option_; 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemOperation::CopyFileProgressCallback file_progress_callback_; 8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOnSameFileSystemImpl); 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Specifically for cross file system copy/move operation, this class creates 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// a snapshot file, validates it if necessary, runs copying process, 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// validates the created file, and removes source file for move (noop for 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// copy). 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class SnapshotCopyOrMoveImpl 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) SnapshotCopyOrMoveImpl( 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner* operation_runner, 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CopyOrMoveOperationDelegate::OperationType operation_type, 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const FileSystemURL& src_url, 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const FileSystemURL& dest_url, 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOperationDelegate::CopyOrMoveOption option, 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CopyOrMoveFileValidatorFactory* validator_factory, 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemOperation::CopyFileProgressCallback& 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_progress_callback) 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : operation_runner_(operation_runner), 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_type_(operation_type), 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) src_url_(src_url), 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) dest_url_(dest_url), 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) option_(option), 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) validator_factory_(validator_factory), 111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_progress_callback_(file_progress_callback), 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_requested_(false), 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_(this) { 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void Run( 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_progress_callback_.Run(0); 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner_->CreateSnapshotFile( 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) src_url_, 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCreateSnapshot, 12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Cancel() OVERRIDE { 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_requested_ = true; 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void RunAfterCreateSnapshot( 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error, 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info, 13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const base::FilePath& platform_path, 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<storage::ShareableFileReference>& file_ref) { 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(error); 14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // For now we assume CreateSnapshotFile always return a valid local file 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // path. 14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!platform_path.empty()); 14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!validator_factory_) { 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // No validation is needed. 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RunAfterPreWriteValidation(platform_path, file_info, file_ref, callback, 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::FILE_OK); 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Run pre write validation. 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PreWriteValidation( 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) platform_path, 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPreWriteValidation, 15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) platform_path, file_info, file_ref, callback)); 16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void RunAfterPreWriteValidation( 16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const base::FilePath& platform_path, 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info, 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<storage::ShareableFileReference>& file_ref, 16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(error); 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |file_ref| is unused but necessary to keep the file alive until 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // CopyInForeignFile() is completed. 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner_->CopyInForeignFile( 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) platform_path, dest_url_, 18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCopyInForeignFile, 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) weak_factory_.GetWeakPtr(), file_info, file_ref, callback)); 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void RunAfterCopyInForeignFile( 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info, 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<storage::ShareableFileReference>& file_ref, 18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(error); 19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_progress_callback_.Run(file_info.size); 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (option_ == FileSystemOperation::OPTION_NONE) { 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunAfterTouchFile(callback, base::File::FILE_OK); 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) operation_runner_->TouchFile( 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dest_url_, base::Time::Now() /* last_access */, 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_info.last_modified, 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::RunAfterTouchFile, 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void RunAfterTouchFile( 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Even if TouchFile is failed, just ignore it. 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) { 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_ABORT); 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |validator_| is NULL when the destination filesystem does not do 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // validation. 22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!validator_) { 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // No validation is needed. 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunAfterPostWriteValidation(callback, base::File::FILE_OK); 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PostWriteValidation( 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPostWriteValidation, 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void RunAfterPostWriteValidation( 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_ABORT); 2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Failed to validate. Remove the destination file. 24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner_->Remove( 24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) dest_url_, true /* recursive */, 24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::DidRemoveDestForError, 24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), error, callback)); 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK); 25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); 25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Remove the source for finalizing move operation. 26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner_->Remove( 26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) src_url_, true /* recursive */, 26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::RunAfterRemoveSourceForMove, 26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void RunAfterRemoveSourceForMove( 26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error == base::File::FILE_ERROR_NOT_FOUND) 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_OK; 27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(error); 27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void DidRemoveDestForError( 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error prior_error, 27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) VLOG(1) << "Error removing destination file after validation error: " 28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) << error; 28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(prior_error); 28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Runs pre-write validation. 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void PreWriteValidation( 29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const base::FilePath& platform_path, 29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback) { 29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(validator_factory_); 29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) validator_.reset( 29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) validator_factory_->CreateCopyOrMoveFileValidator( 29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) src_url_, platform_path)); 29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) validator_->StartPreWriteValidation(callback); 29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Runs post-write validation. 30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void PostWriteValidation( 30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback) { 30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) operation_runner_->CreateSnapshotFile( 30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) dest_url_, 30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind( 30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &SnapshotCopyOrMoveImpl::PostWriteValidationAfterCreateSnapshotFile, 30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void PostWriteValidationAfterCreateSnapshotFile( 31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error, 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info, 31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const base::FilePath& platform_path, 31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<storage::ShareableFileReference>& file_ref) { 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(error); 32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(validator_); 32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Note: file_ref passed here to keep the file alive until after 32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the StartPostWriteValidation operation finishes. 32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) validator_->StartPostWriteValidation( 32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) platform_path, 32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::Bind(&SnapshotCopyOrMoveImpl::DidPostWriteValidation, 32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) weak_factory_.GetWeakPtr(), file_ref, callback)); 33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |file_ref| is unused; it is passed here to make sure the reference is 33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // alive until after post-write validation is complete. 33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void DidPostWriteValidation( 33503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<storage::ShareableFileReference>& file_ref, 33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(error); 33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemOperationRunner* operation_runner_; 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CopyOrMoveOperationDelegate::OperationType operation_type_; 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemURL src_url_; 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileSystemURL dest_url_; 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOperationDelegate::CopyOrMoveOption option_; 34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CopyOrMoveFileValidatorFactory* validator_factory_; 34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<CopyOrMoveFileValidator> validator_; 349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileSystemOperation::CopyFileProgressCallback file_progress_callback_; 3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool cancel_requested_; 35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::WeakPtrFactory<SnapshotCopyOrMoveImpl> weak_factory_; 35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SnapshotCopyOrMoveImpl); 35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// The size of buffer for StreamCopyHelper. 35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kReadBufferSize = 32768; 35768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 35868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// To avoid too many progress callbacks, it should be called less 35968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// frequently than 50ms. 36068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kMinProgressCallbackInvocationSpanInMilliseconds = 50; 36168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Specifically for cross file system copy/move operation, this class uses 36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// stream reader and writer for copying. Validator is not supported, so if 36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// necessary SnapshotCopyOrMoveImpl should be used. 36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class StreamCopyOrMoveImpl 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public: 36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) StreamCopyOrMoveImpl( 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperationRunner* operation_runner, 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FileSystemContext* file_system_context, 37168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOperationDelegate::OperationType operation_type, 37268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const FileSystemURL& src_url, 37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const FileSystemURL& dest_url, 3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CopyOrMoveOperationDelegate::CopyOrMoveOption option, 37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<storage::FileStreamReader> reader, 37668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<FileStreamWriter> writer, 37768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const FileSystemOperation::CopyFileProgressCallback& 37868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_progress_callback) 37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : operation_runner_(operation_runner), 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_system_context_(file_system_context), 38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) operation_type_(operation_type), 38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) src_url_(src_url), 38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) dest_url_(dest_url), 3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) option_(option), 38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reader_(reader.Pass()), 38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) writer_(writer.Pass()), 38768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_progress_callback_(file_progress_callback), 3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_requested_(false), 38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) weak_factory_(this) {} 39068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 39168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual void Run( 39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { 39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Reader can be created even if the entry does not exist or the entry is 39468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // a directory. To check errors before destination file creation, 39568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // check metadata first. 39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) operation_runner_->GetMetadata( 39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) src_url_, 39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&StreamCopyOrMoveImpl::RunAfterGetMetadataForSource, 39968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 40068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Cancel() OVERRIDE { 4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_requested_ = true; 4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (copy_helper_) 4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) copy_helper_->Cancel(); 4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 40868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private: 4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void NotifyOnStartUpdate(const FileSystemURL& url) { 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (file_system_context_->GetUpdateObservers(url.type())) { 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_system_context_->GetUpdateObservers(url.type()) 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ->Notify(&FileUpdateObserver::OnStartUpdate, MakeTuple(url)); 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void NotifyOnModifyFile(const FileSystemURL& url) { 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (file_system_context_->GetChangeObservers(url.type())) { 4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_system_context_->GetChangeObservers(url.type()) 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ->Notify(&FileChangeObserver::OnModifyFile, MakeTuple(url)); 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void NotifyOnEndUpdate(const FileSystemURL& url) { 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (file_system_context_->GetUpdateObservers(url.type())) { 4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_system_context_->GetUpdateObservers(url.type()) 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ->Notify(&FileUpdateObserver::OnEndUpdate, MakeTuple(url)); 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 43068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void RunAfterGetMetadataForSource( 43168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error, 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback.Run(error); 43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 44068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 44268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (file_info.is_directory) { 44368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If not a directory, failed with appropriate error code. 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_NOT_A_FILE); 44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 44768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 44868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // To use FileStreamWriter, we need to ensure the destination file exists. 44968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) operation_runner_->CreateFile( 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dest_url_, 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci true /* exclusive */, 45268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&StreamCopyOrMoveImpl::RunAfterCreateFileForDestination, 4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), 4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_info.last_modified)); 45668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 45768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 45868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void RunAfterCreateFileForDestination( 45968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::Time& last_modified, 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 4624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This conversion is to return the consistent status code with 4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // FileSystemFileUtil::Copy. 4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error == base::File::FILE_ERROR_NOT_A_FILE) 4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error = base::File::FILE_ERROR_INVALID_OPERATION; 4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error != base::File::FILE_OK && 4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error != base::File::FILE_ERROR_EXISTS) { 4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback.Run(error); 4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error == base::File::FILE_ERROR_EXISTS) { 4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci operation_runner_->Truncate( 4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dest_url_, 4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 0 /* length */, 4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&StreamCopyOrMoveImpl::RunAfterTruncateForDestination, 4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.GetWeakPtr(), 4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, 4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci last_modified)); 4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RunAfterTruncateForDestination( 4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback, last_modified, base::File::FILE_OK); 4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void RunAfterTruncateForDestination( 4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const CopyOrMoveOperationDelegate::StatusCallback& callback, 4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::Time& last_modified, 4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::File::Error error) { 4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cancel_requested_) 4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error = base::File::FILE_ERROR_ABORT; 4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback.Run(error); 49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 50068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool need_flush = dest_url_.mount_option().copy_sync_option() == 50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::COPY_SYNC_OPTION_SYNC; 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyOnStartUpdate(dest_url_); 50568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!copy_helper_); 50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) copy_helper_.reset( 50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new CopyOrMoveOperationDelegate::StreamCopyHelper( 50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reader_.Pass(), writer_.Pass(), 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) need_flush, 51068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) kReadBufferSize, 51168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_progress_callback_, 51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::TimeDelta::FromMilliseconds( 51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) kMinProgressCallbackInvocationSpanInMilliseconds))); 51468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) copy_helper_->Run( 51568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&StreamCopyOrMoveImpl::RunAfterStreamCopy, 5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback, last_modified)); 51768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 51868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 51968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void RunAfterStreamCopy( 52068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::Time& last_modified, 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyOnModifyFile(dest_url_); 5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyOnEndUpdate(dest_url_); 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 52968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback.Run(error); 53068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 53168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (option_ == FileSystemOperation::OPTION_NONE) { 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunAfterTouchFile(callback, base::File::FILE_OK); 5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) operation_runner_->TouchFile( 5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dest_url_, base::Time::Now() /* last_access */, last_modified, 5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&StreamCopyOrMoveImpl::RunAfterTouchFile, 5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void RunAfterTouchFile( 5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Even if TouchFile is failed, just ignore it. 5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) { 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_ABORT); 5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK); 55568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 55668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 55768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); 55968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Remove the source for finalizing move operation. 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) operation_runner_->Remove( 56268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) src_url_, false /* recursive */, 56368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&StreamCopyOrMoveImpl::RunAfterRemoveForMove, 56468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 56568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 56668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void RunAfterRemoveForMove( 56868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CopyOrMoveOperationDelegate::StatusCallback& callback, 5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) 5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_ABORT; 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error == base::File::FILE_ERROR_NOT_FOUND) 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_OK; 57468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback.Run(error); 57568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 57668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperationRunner* operation_runner_; 5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<FileSystemContext> file_system_context_; 57968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOperationDelegate::OperationType operation_type_; 58068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemURL src_url_; 58168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemURL dest_url_; 5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CopyOrMoveOperationDelegate::CopyOrMoveOption option_; 58303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<storage::FileStreamReader> reader_; 58468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<FileStreamWriter> writer_; 58568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperation::CopyFileProgressCallback file_progress_callback_; 58668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; 5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool cancel_requested_; 58868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::WeakPtrFactory<StreamCopyOrMoveImpl> weak_factory_; 58968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(StreamCopyOrMoveImpl); 59068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 59168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 59258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} // namespace 59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 59468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)CopyOrMoveOperationDelegate::StreamCopyHelper::StreamCopyHelper( 59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<storage::FileStreamReader> reader, 59668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<FileStreamWriter> writer, 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool need_flush, 59868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int buffer_size, 59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const FileSystemOperation::CopyFileProgressCallback& file_progress_callback, 60068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const base::TimeDelta& min_progress_callback_invocation_span) 60168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : reader_(reader.Pass()), 60268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) writer_(writer.Pass()), 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) need_flush_(need_flush), 60468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_progress_callback_(file_progress_callback), 60568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) io_buffer_(new net::IOBufferWithSize(buffer_size)), 60668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) num_copied_bytes_(0), 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) previous_flush_offset_(0), 60868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) min_progress_callback_invocation_span_( 60968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) min_progress_callback_invocation_span), 6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_requested_(false), 61168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_(this) { 61268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 61368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 61468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)CopyOrMoveOperationDelegate::StreamCopyHelper::~StreamCopyHelper() { 61568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 61668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 61768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::Run( 61868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const StatusCallback& callback) { 61968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_progress_callback_.Run(0); 62068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) last_progress_callback_invocation_time_ = base::Time::Now(); 62168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Read(callback); 62268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::Cancel() { 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cancel_requested_ = true; 6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::Read( 62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const StatusCallback& callback) { 63068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int result = reader_->Read( 63168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) io_buffer_.get(), io_buffer_->size(), 63268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&StreamCopyHelper::DidRead, 63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 63468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result != net::ERR_IO_PENDING) 63568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DidRead(callback, result); 63668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 63768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 63868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::DidRead( 63968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const StatusCallback& callback, int result) { 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) { 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_ABORT); 6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 64568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result < 0) { 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(NetErrorToFileError(result)); 64768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 64868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 64968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 65068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result == 0) { 65168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Here is the EOF. 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (need_flush_) 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Flush(callback, true /* is_eof */); 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK); 65668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 65768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 65868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 65968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Write(callback, new net::DrainableIOBuffer(io_buffer_.get(), result)); 66068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 66168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 66268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::Write( 66368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const StatusCallback& callback, 66468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<net::DrainableIOBuffer> buffer) { 66568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_GT(buffer->BytesRemaining(), 0); 66668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 66768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int result = writer_->Write( 66868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) buffer.get(), buffer->BytesRemaining(), 66968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&StreamCopyHelper::DidWrite, 67068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_.GetWeakPtr(), callback, buffer)); 67168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result != net::ERR_IO_PENDING) 67268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DidWrite(callback, buffer, result); 67368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 67468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 67568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::DidWrite( 67668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const StatusCallback& callback, 67768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<net::DrainableIOBuffer> buffer, 67868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int result) { 6794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (cancel_requested_) { 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_ABORT); 6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 6824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 68468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (result < 0) { 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(NetErrorToFileError(result)); 68668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 68768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 68868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 68968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) buffer->DidConsume(result); 69068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) num_copied_bytes_ += result; 69168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 69268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Check the elapsed time since last |file_progress_callback_| invocation. 69368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Time now = base::Time::Now(); 69468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (now - last_progress_callback_invocation_time_ >= 69568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) min_progress_callback_invocation_span_) { 69668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_progress_callback_.Run(num_copied_bytes_); 69768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) last_progress_callback_invocation_time_ = now; 69868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 69968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 70068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (buffer->BytesRemaining() > 0) { 70168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Write(callback, buffer); 70268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 70368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 70468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (need_flush_ && 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (num_copied_bytes_ - previous_flush_offset_) > kFlushIntervalInBytes) { 7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Flush(callback, false /* not is_eof */); 7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 7095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Read(callback); 7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::Flush( 7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StatusCallback& callback, bool is_eof) { 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int result = writer_->Flush( 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&StreamCopyHelper::DidFlush, 7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_factory_.GetWeakPtr(), callback, is_eof)); 7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result != net::ERR_IO_PENDING) 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DidFlush(callback, is_eof, result); 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CopyOrMoveOperationDelegate::StreamCopyHelper::DidFlush( 7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const StatusCallback& callback, bool is_eof, int result) { 7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (cancel_requested_) { 7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_ERROR_ABORT); 7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) previous_flush_offset_ = num_copied_bytes_; 7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_eof) 7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(NetErrorToFileError(result)); 7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Read(callback); 73468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 73558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)CopyOrMoveOperationDelegate::CopyOrMoveOperationDelegate( 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileSystemContext* file_system_context, 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& src_root, 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& dest_root, 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OperationType operation_type, 74168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CopyOrMoveOption option, 742d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const CopyProgressCallback& progress_callback, 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback) 744868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : RecursiveOperationDelegate(file_system_context), 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) src_root_(src_root), 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dest_root_(dest_root), 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) operation_type_(operation_type), 74868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) option_(option), 749d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) progress_callback_(progress_callback), 750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch callback_(callback), 751ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch weak_factory_(this) { 75290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) same_file_system_ = src_root_.IsInSameFileSystem(dest_root_); 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)CopyOrMoveOperationDelegate::~CopyOrMoveOperationDelegate() { 75658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) STLDeleteElements(&running_copy_set_); 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void CopyOrMoveOperationDelegate::Run() { 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not supported; this should never be called. 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void CopyOrMoveOperationDelegate::RunRecursively() { 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Perform light-weight checks first. 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It is an error to try to copy/move an entry into its child. 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (same_file_system_ && src_root_.path().IsParent(dest_root_.path())) { 7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_INVALID_OPERATION); 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (same_file_system_ && src_root_.path() == dest_root_.path()) { 7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // In JS API this should return error, but we return success because Pepper 7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // wants to return success and we have a code path that returns error in 7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Blink for JS (http://crbug.com/329517). 7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_OK); 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 781d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Start to process the source directory recursively. 782d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(kinuko): This could be too expensive for same_file_system_==true 783d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // and operation==MOVE case, probably we can just rename the root directory. 784d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // http://crbug.com/172187 785d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) StartRecursiveOperation(src_root_, callback_); 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 788d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::ProcessFile( 789d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& src_url, 790d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback) { 79168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!progress_callback_.is_null()) { 79268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) progress_callback_.Run( 79368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperation::BEGIN_COPY_ENTRY, src_url, FileSystemURL(), 0); 79468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FileSystemURL dest_url = CreateDestURL(src_url); 797d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CopyOrMoveImpl* impl = NULL; 79803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (same_file_system_ && 79903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) (file_system_context() 80003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ->GetFileSystemBackend(src_url.type()) 80103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ->HasInplaceCopyImplementation(src_url.type()) || 8021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci operation_type_ == OPERATION_MOVE)) { 803d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) impl = new CopyOrMoveOnSameFileSystemImpl( 80468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) operation_runner(), operation_type_, src_url, dest_url, option_, 805d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, 806d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) weak_factory_.GetWeakPtr(), src_url)); 807d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 808d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Cross filesystem case. 8095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error = base::File::FILE_ERROR_FAILED; 810d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CopyOrMoveFileValidatorFactory* validator_factory = 811d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) file_system_context()->GetCopyOrMoveFileValidatorFactory( 812d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dest_root_.type(), &error); 8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 814d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback.Run(error); 815d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 816d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!validator_factory) { 81903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_ptr<storage::FileStreamReader> reader = 82068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_system_context()->CreateFileStreamReader( 8211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci src_url, 0 /* offset */, storage::kMaximumLength, base::Time()); 82268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<FileStreamWriter> writer = 82368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) file_system_context()->CreateFileStreamWriter(dest_url, 0); 82468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (reader && writer) { 82568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) impl = new StreamCopyOrMoveImpl( 8261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci operation_runner(), 8271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci file_system_context(), 8281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci operation_type_, 8291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci src_url, 8301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dest_url, 8311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci option_, 8321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reader.Pass(), 8331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci writer.Pass(), 83468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, 8351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.GetWeakPtr(), 8361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci src_url)); 83768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 83868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 83968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 84068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!impl) { 84168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) impl = new SnapshotCopyOrMoveImpl( 84268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) operation_runner(), operation_type_, src_url, dest_url, option_, 84368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) validator_factory, 84468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, 84568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_.GetWeakPtr(), src_url)); 84668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 849d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Register the running task. 850d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) running_copy_set_.insert(impl); 85168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) impl->Run(base::Bind( 85268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &CopyOrMoveOperationDelegate::DidCopyOrMoveFile, 85368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_.GetWeakPtr(), src_url, dest_url, callback, impl)); 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 856d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::ProcessDirectory( 857d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& src_url, 858d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback) { 859d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (src_url == src_root_) { 860d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The src_root_ looks to be a directory. 861d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Try removing the dest_root_ to see if it exists and/or it is an 862d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // empty directory. 863d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We do not invoke |progress_callback_| for source root, because it is 864d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // already called in ProcessFile(). 865d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation_runner()->RemoveDirectory( 866d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dest_root_, 867d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&CopyOrMoveOperationDelegate::DidTryRemoveDestRoot, 868d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 87268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!progress_callback_.is_null()) { 87368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) progress_callback_.Run( 87468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperation::BEGIN_COPY_ENTRY, src_url, FileSystemURL(), 0); 87568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 876d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 877d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessDirectoryInternal(src_url, CreateDestURL(src_url), callback); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 880d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::PostProcessDirectory( 881d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& src_url, 882d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback) { 8834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (option_ == FileSystemOperation::OPTION_NONE) { 8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PostProcessDirectoryAfterTouchFile( 8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) src_url, callback, base::File::FILE_OK); 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) operation_runner()->GetMetadata( 8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) src_url, 8914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind( 8924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &CopyOrMoveOperationDelegate::PostProcessDirectoryAfterGetMetadata, 8934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), src_url, callback)); 8944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CopyOrMoveOperationDelegate::OnCancel() { 8974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Request to cancel all running Copy/Move file. 8984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (std::set<CopyOrMoveImpl*>::iterator iter = running_copy_set_.begin(); 8994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iter != running_copy_set_.end(); ++iter) 9004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (*iter)->Cancel(); 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 903d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::DidCopyOrMoveFile( 904d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& src_url, 90568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const FileSystemURL& dest_url, 906a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch const StatusCallback& callback, 907d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CopyOrMoveImpl* impl, 9085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 909d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) running_copy_set_.erase(impl); 910d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) delete impl; 911d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!progress_callback_.is_null() && error == base::File::FILE_OK) { 91368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) progress_callback_.Run( 91468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperation::END_COPY_ENTRY, src_url, dest_url, 0); 91568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 916d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 91758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) callback.Run(error); 918a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 919a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 920d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::DidTryRemoveDestRoot( 921d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback, 9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 9235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error == base::File::FILE_ERROR_NOT_A_DIRECTORY) { 9245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback_.Run(base::File::FILE_ERROR_INVALID_OPERATION); 925d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 926d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK && 9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error != base::File::FILE_ERROR_NOT_FOUND) { 929d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback_.Run(error); 930d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 931d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 932d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 933d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ProcessDirectoryInternal(src_root_, dest_root_, callback); 934d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 935d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 936d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::ProcessDirectoryInternal( 93758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const FileSystemURL& src_url, 93858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const FileSystemURL& dest_url, 93958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const StatusCallback& callback) { 940d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If operation_type == Move we may need to record directories and 941d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // restore directory timestamps in the end, though it may have 942d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // negative performance impact. 943d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // See http://crbug.com/171284 for more details. 944d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) operation_runner()->CreateDirectory( 945d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) dest_url, false /* exclusive */, false /* recursive */, 946d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Bind(&CopyOrMoveOperationDelegate::DidCreateDirectory, 94768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) weak_factory_.GetWeakPtr(), src_url, dest_url, callback)); 948d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 949a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 950d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::DidCreateDirectory( 951d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& src_url, 95268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const FileSystemURL& dest_url, 953d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const StatusCallback& callback, 9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!progress_callback_.is_null() && error == base::File::FILE_OK) { 95668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) progress_callback_.Run( 95768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperation::END_COPY_ENTRY, src_url, dest_url, 0); 95868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 959a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 960d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) callback.Run(error); 961a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch} 962a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 9634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CopyOrMoveOperationDelegate::PostProcessDirectoryAfterGetMetadata( 9644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FileSystemURL& src_url, 9654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const StatusCallback& callback, 9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error, 9675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 9685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) { 9694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Ignore the error, and run post process which should run after TouchFile. 9704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PostProcessDirectoryAfterTouchFile( 9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) src_url, callback, base::File::FILE_OK); 9724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 9734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 9744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) operation_runner()->TouchFile( 9764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CreateDestURL(src_url), base::Time::Now() /* last access */, 9774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) file_info.last_modified, 9784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind( 9794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &CopyOrMoveOperationDelegate::PostProcessDirectoryAfterTouchFile, 9804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), src_url, callback)); 9814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 9824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void CopyOrMoveOperationDelegate::PostProcessDirectoryAfterTouchFile( 9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FileSystemURL& src_url, 9854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const StatusCallback& callback, 9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 9874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Even if the TouchFile is failed, just ignore it. 9884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (operation_type_ == OPERATION_COPY) { 9905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(base::File::FILE_OK); 9914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 9924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 9934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_EQ(OPERATION_MOVE, operation_type_); 9954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 9964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // All files and subdirectories in the directory should be moved here, 9974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // so remove the source directory for finalizing move operation. 9984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) operation_runner()->Remove( 9994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) src_url, false /* recursive */, 10004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, 10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), callback)); 10024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 10034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1004d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::DidRemoveSourceForMove( 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const StatusCallback& callback, 10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error == base::File::FILE_ERROR_NOT_FOUND) 10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_OK; 10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(error); 10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CopyOrMoveOperationDelegate::OnCopyFileProgress( 1013d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const FileSystemURL& src_url, int64 size) { 101468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!progress_callback_.is_null()) { 101568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) progress_callback_.Run( 101668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FileSystemOperation::PROGRESS, src_url, FileSystemURL(), size); 101768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 1018d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1019d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FileSystemURL& src_url) const { 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(src_root_.type(), src_url.type()); 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(src_root_.origin(), src_url.origin()); 10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath relative = dest_root_.virtual_path(); 10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), 10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &relative); 10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return file_system_context()->CreateCrackedFileSystemURL( 10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dest_root_.origin(), 10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dest_root_.mount_type(), 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) relative); 10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 103403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace storage 1035