1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef WEBKIT_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_ 6 #define WEBKIT_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_ 7 8 #include <set> 9 #include <stack> 10 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/time/time.h" 14 #include "webkit/browser/fileapi/recursive_operation_delegate.h" 15 16 namespace net { 17 class DrainableIOBuffer; 18 class IOBufferWithSize; 19 } 20 21 namespace webkit_blob { 22 class FileStreamReader; 23 class ShareableFileReference; 24 } 25 26 namespace fileapi { 27 28 class CopyOrMoveFileValidator; 29 class FileStreamWriter; 30 31 // A delegate class for recursive copy or move operations. 32 class CopyOrMoveOperationDelegate 33 : public RecursiveOperationDelegate { 34 public: 35 class CopyOrMoveImpl; 36 typedef FileSystemOperation::CopyProgressCallback CopyProgressCallback; 37 typedef FileSystemOperation::CopyOrMoveOption CopyOrMoveOption; 38 39 enum OperationType { 40 OPERATION_COPY, 41 OPERATION_MOVE 42 }; 43 44 // Helper to copy a file by reader and writer streams. 45 // Export for testing. 46 class WEBKIT_STORAGE_BROWSER_EXPORT StreamCopyHelper { 47 public: 48 StreamCopyHelper( 49 scoped_ptr<webkit_blob::FileStreamReader> reader, 50 scoped_ptr<FileStreamWriter> writer, 51 bool need_flush, 52 int buffer_size, 53 const FileSystemOperation::CopyFileProgressCallback& 54 file_progress_callback, 55 const base::TimeDelta& min_progress_callback_invocation_span); 56 ~StreamCopyHelper(); 57 58 void Run(const StatusCallback& callback); 59 60 // Requests cancelling. After the cancelling is done, |callback| passed to 61 // Run will be called. 62 void Cancel(); 63 64 private: 65 // Reads the content from the |reader_|. 66 void Read(const StatusCallback& callback); 67 void DidRead(const StatusCallback& callback, int result); 68 69 // Writes the content in |buffer| to |writer_|. 70 void Write(const StatusCallback& callback, 71 scoped_refptr<net::DrainableIOBuffer> buffer); 72 void DidWrite(const StatusCallback& callback, 73 scoped_refptr<net::DrainableIOBuffer> buffer, int result); 74 75 // Flushes the written content in |writer_|. 76 void Flush(const StatusCallback& callback, bool is_eof); 77 void DidFlush(const StatusCallback& callback, bool is_eof, int result); 78 79 scoped_ptr<webkit_blob::FileStreamReader> reader_; 80 scoped_ptr<FileStreamWriter> writer_; 81 const bool need_flush_; 82 FileSystemOperation::CopyFileProgressCallback file_progress_callback_; 83 scoped_refptr<net::IOBufferWithSize> io_buffer_; 84 int64 num_copied_bytes_; 85 int64 previous_flush_offset_; 86 base::Time last_progress_callback_invocation_time_; 87 base::TimeDelta min_progress_callback_invocation_span_; 88 bool cancel_requested_; 89 base::WeakPtrFactory<StreamCopyHelper> weak_factory_; 90 DISALLOW_COPY_AND_ASSIGN(StreamCopyHelper); 91 }; 92 93 CopyOrMoveOperationDelegate( 94 FileSystemContext* file_system_context, 95 const FileSystemURL& src_root, 96 const FileSystemURL& dest_root, 97 OperationType operation_type, 98 CopyOrMoveOption option, 99 const CopyProgressCallback& progress_callback, 100 const StatusCallback& callback); 101 virtual ~CopyOrMoveOperationDelegate(); 102 103 // RecursiveOperationDelegate overrides: 104 virtual void Run() OVERRIDE; 105 virtual void RunRecursively() OVERRIDE; 106 virtual void ProcessFile(const FileSystemURL& url, 107 const StatusCallback& callback) OVERRIDE; 108 virtual void ProcessDirectory(const FileSystemURL& url, 109 const StatusCallback& callback) OVERRIDE; 110 virtual void PostProcessDirectory(const FileSystemURL& url, 111 const StatusCallback& callback) OVERRIDE; 112 113 114 protected: 115 virtual void OnCancel() OVERRIDE; 116 117 private: 118 void DidCopyOrMoveFile(const FileSystemURL& src_url, 119 const FileSystemURL& dest_url, 120 const StatusCallback& callback, 121 CopyOrMoveImpl* impl, 122 base::PlatformFileError error); 123 void DidTryRemoveDestRoot(const StatusCallback& callback, 124 base::PlatformFileError error); 125 void ProcessDirectoryInternal(const FileSystemURL& src_url, 126 const FileSystemURL& dest_url, 127 const StatusCallback& callback); 128 void DidCreateDirectory(const FileSystemURL& src_url, 129 const FileSystemURL& dest_url, 130 const StatusCallback& callback, 131 base::PlatformFileError error); 132 void PostProcessDirectoryAfterGetMetadata( 133 const FileSystemURL& src_url, 134 const StatusCallback& callback, 135 base::PlatformFileError error, 136 const base::PlatformFileInfo& file_info); 137 void PostProcessDirectoryAfterTouchFile(const FileSystemURL& src_url, 138 const StatusCallback& callback, 139 base::PlatformFileError error); 140 void DidRemoveSourceForMove(const StatusCallback& callback, 141 base::PlatformFileError error); 142 143 void OnCopyFileProgress(const FileSystemURL& src_url, int64 size); 144 FileSystemURL CreateDestURL(const FileSystemURL& src_url) const; 145 146 FileSystemURL src_root_; 147 FileSystemURL dest_root_; 148 bool same_file_system_; 149 OperationType operation_type_; 150 CopyOrMoveOption option_; 151 CopyProgressCallback progress_callback_; 152 StatusCallback callback_; 153 154 std::set<CopyOrMoveImpl*> running_copy_set_; 155 base::WeakPtrFactory<CopyOrMoveOperationDelegate> weak_factory_; 156 157 DISALLOW_COPY_AND_ASSIGN(CopyOrMoveOperationDelegate); 158 }; 159 160 } // namespace fileapi 161 162 #endif // WEBKIT_BROWSER_FILEAPI_COPY_OR_MOVE_OPERATION_DELEGATE_H_ 163