| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/browser/fileapi/copy_or_move_operation_delegate.h" | 5 #include "storage/browser/fileapi/copy_or_move_operation_delegate.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| 11 #include "webkit/browser/blob/file_stream_reader.h" | 11 #include "storage/browser/blob/file_stream_reader.h" |
| 12 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" | 12 #include "storage/browser/fileapi/copy_or_move_file_validator.h" |
| 13 #include "webkit/browser/fileapi/file_stream_writer.h" | 13 #include "storage/browser/fileapi/file_stream_writer.h" |
| 14 #include "webkit/browser/fileapi/file_system_context.h" | 14 #include "storage/browser/fileapi/file_system_context.h" |
| 15 #include "webkit/browser/fileapi/file_system_operation_runner.h" | 15 #include "storage/browser/fileapi/file_system_operation_runner.h" |
| 16 #include "webkit/browser/fileapi/file_system_url.h" | 16 #include "storage/browser/fileapi/file_system_url.h" |
| 17 #include "webkit/browser/fileapi/recursive_operation_delegate.h" | 17 #include "storage/browser/fileapi/recursive_operation_delegate.h" |
| 18 #include "webkit/common/blob/shareable_file_reference.h" | 18 #include "storage/common/blob/shareable_file_reference.h" |
| 19 #include "webkit/common/fileapi/file_system_util.h" | 19 #include "storage/common/fileapi/file_system_util.h" |
| 20 | 20 |
| 21 namespace fileapi { | 21 namespace storage { |
| 22 | 22 |
| 23 const int64 kFlushIntervalInBytes = 10 << 20; // 10MB. | 23 const int64 kFlushIntervalInBytes = 10 << 20; // 10MB. |
| 24 | 24 |
| 25 class CopyOrMoveOperationDelegate::CopyOrMoveImpl { | 25 class CopyOrMoveOperationDelegate::CopyOrMoveImpl { |
| 26 public: | 26 public: |
| 27 virtual ~CopyOrMoveImpl() {} | 27 virtual ~CopyOrMoveImpl() {} |
| 28 virtual void Run( | 28 virtual void Run( |
| 29 const CopyOrMoveOperationDelegate::StatusCallback& callback) = 0; | 29 const CopyOrMoveOperationDelegate::StatusCallback& callback) = 0; |
| 30 virtual void Cancel() = 0; | 30 virtual void Cancel() = 0; |
| 31 | 31 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 49 const FileSystemURL& src_url, | 49 const FileSystemURL& src_url, |
| 50 const FileSystemURL& dest_url, | 50 const FileSystemURL& dest_url, |
| 51 CopyOrMoveOperationDelegate::CopyOrMoveOption option, | 51 CopyOrMoveOperationDelegate::CopyOrMoveOption option, |
| 52 const FileSystemOperation::CopyFileProgressCallback& | 52 const FileSystemOperation::CopyFileProgressCallback& |
| 53 file_progress_callback) | 53 file_progress_callback) |
| 54 : operation_runner_(operation_runner), | 54 : operation_runner_(operation_runner), |
| 55 operation_type_(operation_type), | 55 operation_type_(operation_type), |
| 56 src_url_(src_url), | 56 src_url_(src_url), |
| 57 dest_url_(dest_url), | 57 dest_url_(dest_url), |
| 58 option_(option), | 58 option_(option), |
| 59 file_progress_callback_(file_progress_callback) { | 59 file_progress_callback_(file_progress_callback) {} |
| 60 } | |
| 61 | 60 |
| 62 virtual void Run( | 61 virtual void Run( |
| 63 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { | 62 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { |
| 64 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_MOVE) { | 63 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_MOVE) { |
| 65 operation_runner_->MoveFileLocal(src_url_, dest_url_, option_, callback); | 64 operation_runner_->MoveFileLocal(src_url_, dest_url_, option_, callback); |
| 66 } else { | 65 } else { |
| 67 operation_runner_->CopyFileLocal( | 66 operation_runner_->CopyFileLocal( |
| 68 src_url_, dest_url_, option_, file_progress_callback_, callback); | 67 src_url_, dest_url_, option_, file_progress_callback_, callback); |
| 69 } | 68 } |
| 70 } | 69 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 const FileSystemOperation::CopyFileProgressCallback& | 101 const FileSystemOperation::CopyFileProgressCallback& |
| 103 file_progress_callback) | 102 file_progress_callback) |
| 104 : operation_runner_(operation_runner), | 103 : operation_runner_(operation_runner), |
| 105 operation_type_(operation_type), | 104 operation_type_(operation_type), |
| 106 src_url_(src_url), | 105 src_url_(src_url), |
| 107 dest_url_(dest_url), | 106 dest_url_(dest_url), |
| 108 option_(option), | 107 option_(option), |
| 109 validator_factory_(validator_factory), | 108 validator_factory_(validator_factory), |
| 110 file_progress_callback_(file_progress_callback), | 109 file_progress_callback_(file_progress_callback), |
| 111 cancel_requested_(false), | 110 cancel_requested_(false), |
| 112 weak_factory_(this) { | 111 weak_factory_(this) {} |
| 113 } | |
| 114 | 112 |
| 115 virtual void Run( | 113 virtual void Run( |
| 116 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { | 114 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { |
| 117 file_progress_callback_.Run(0); | 115 file_progress_callback_.Run(0); |
| 118 operation_runner_->CreateSnapshotFile( | 116 operation_runner_->CreateSnapshotFile( |
| 119 src_url_, | 117 src_url_, |
| 120 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCreateSnapshot, | 118 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCreateSnapshot, |
| 121 weak_factory_.GetWeakPtr(), callback)); | 119 weak_factory_.GetWeakPtr(), |
| 120 callback)); |
| 122 } | 121 } |
| 123 | 122 |
| 124 virtual void Cancel() OVERRIDE { | 123 virtual void Cancel() OVERRIDE { cancel_requested_ = true; } |
| 125 cancel_requested_ = true; | |
| 126 } | |
| 127 | 124 |
| 128 private: | 125 private: |
| 129 void RunAfterCreateSnapshot( | 126 void RunAfterCreateSnapshot( |
| 130 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 127 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 131 base::File::Error error, | 128 base::File::Error error, |
| 132 const base::File::Info& file_info, | 129 const base::File::Info& file_info, |
| 133 const base::FilePath& platform_path, | 130 const base::FilePath& platform_path, |
| 134 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { | 131 const scoped_refptr<storage::ShareableFileReference>& file_ref) { |
| 135 if (cancel_requested_) | 132 if (cancel_requested_) |
| 136 error = base::File::FILE_ERROR_ABORT; | 133 error = base::File::FILE_ERROR_ABORT; |
| 137 | 134 |
| 138 if (error != base::File::FILE_OK) { | 135 if (error != base::File::FILE_OK) { |
| 139 callback.Run(error); | 136 callback.Run(error); |
| 140 return; | 137 return; |
| 141 } | 138 } |
| 142 | 139 |
| 143 // For now we assume CreateSnapshotFile always return a valid local file | 140 // For now we assume CreateSnapshotFile always return a valid local file |
| 144 // path. | 141 // path. |
| 145 DCHECK(!platform_path.empty()); | 142 DCHECK(!platform_path.empty()); |
| 146 | 143 |
| 147 if (!validator_factory_) { | 144 if (!validator_factory_) { |
| 148 // No validation is needed. | 145 // No validation is needed. |
| 149 RunAfterPreWriteValidation(platform_path, file_info, file_ref, callback, | 146 RunAfterPreWriteValidation( |
| 150 base::File::FILE_OK); | 147 platform_path, file_info, file_ref, callback, base::File::FILE_OK); |
| 151 return; | 148 return; |
| 152 } | 149 } |
| 153 | 150 |
| 154 // Run pre write validation. | 151 // Run pre write validation. |
| 155 PreWriteValidation( | 152 PreWriteValidation( |
| 156 platform_path, | 153 platform_path, |
| 157 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPreWriteValidation, | 154 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPreWriteValidation, |
| 158 weak_factory_.GetWeakPtr(), | 155 weak_factory_.GetWeakPtr(), |
| 159 platform_path, file_info, file_ref, callback)); | 156 platform_path, |
| 157 file_info, |
| 158 file_ref, |
| 159 callback)); |
| 160 } | 160 } |
| 161 | 161 |
| 162 void RunAfterPreWriteValidation( | 162 void RunAfterPreWriteValidation( |
| 163 const base::FilePath& platform_path, | 163 const base::FilePath& platform_path, |
| 164 const base::File::Info& file_info, | 164 const base::File::Info& file_info, |
| 165 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref, | 165 const scoped_refptr<storage::ShareableFileReference>& file_ref, |
| 166 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 166 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 167 base::File::Error error) { | 167 base::File::Error error) { |
| 168 if (cancel_requested_) | 168 if (cancel_requested_) |
| 169 error = base::File::FILE_ERROR_ABORT; | 169 error = base::File::FILE_ERROR_ABORT; |
| 170 | 170 |
| 171 if (error != base::File::FILE_OK) { | 171 if (error != base::File::FILE_OK) { |
| 172 callback.Run(error); | 172 callback.Run(error); |
| 173 return; | 173 return; |
| 174 } | 174 } |
| 175 | 175 |
| 176 // |file_ref| is unused but necessary to keep the file alive until | 176 // |file_ref| is unused but necessary to keep the file alive until |
| 177 // CopyInForeignFile() is completed. | 177 // CopyInForeignFile() is completed. |
| 178 operation_runner_->CopyInForeignFile( | 178 operation_runner_->CopyInForeignFile( |
| 179 platform_path, dest_url_, | 179 platform_path, |
| 180 dest_url_, |
| 180 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCopyInForeignFile, | 181 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterCopyInForeignFile, |
| 181 weak_factory_.GetWeakPtr(), file_info, file_ref, callback)); | 182 weak_factory_.GetWeakPtr(), |
| 183 file_info, |
| 184 file_ref, |
| 185 callback)); |
| 182 } | 186 } |
| 183 | 187 |
| 184 void RunAfterCopyInForeignFile( | 188 void RunAfterCopyInForeignFile( |
| 185 const base::File::Info& file_info, | 189 const base::File::Info& file_info, |
| 186 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref, | 190 const scoped_refptr<storage::ShareableFileReference>& file_ref, |
| 187 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 191 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 188 base::File::Error error) { | 192 base::File::Error error) { |
| 189 if (cancel_requested_) | 193 if (cancel_requested_) |
| 190 error = base::File::FILE_ERROR_ABORT; | 194 error = base::File::FILE_ERROR_ABORT; |
| 191 | 195 |
| 192 if (error != base::File::FILE_OK) { | 196 if (error != base::File::FILE_OK) { |
| 193 callback.Run(error); | 197 callback.Run(error); |
| 194 return; | 198 return; |
| 195 } | 199 } |
| 196 | 200 |
| 197 file_progress_callback_.Run(file_info.size); | 201 file_progress_callback_.Run(file_info.size); |
| 198 | 202 |
| 199 if (option_ == FileSystemOperation::OPTION_NONE) { | 203 if (option_ == FileSystemOperation::OPTION_NONE) { |
| 200 RunAfterTouchFile(callback, base::File::FILE_OK); | 204 RunAfterTouchFile(callback, base::File::FILE_OK); |
| 201 return; | 205 return; |
| 202 } | 206 } |
| 203 | 207 |
| 204 operation_runner_->TouchFile( | 208 operation_runner_->TouchFile( |
| 205 dest_url_, base::Time::Now() /* last_access */, | 209 dest_url_, |
| 210 base::Time::Now() /* last_access */, |
| 206 file_info.last_modified, | 211 file_info.last_modified, |
| 207 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterTouchFile, | 212 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterTouchFile, |
| 208 weak_factory_.GetWeakPtr(), callback)); | 213 weak_factory_.GetWeakPtr(), |
| 214 callback)); |
| 209 } | 215 } |
| 210 | 216 |
| 211 void RunAfterTouchFile( | 217 void RunAfterTouchFile( |
| 212 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 218 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 213 base::File::Error error) { | 219 base::File::Error error) { |
| 214 // Even if TouchFile is failed, just ignore it. | 220 // Even if TouchFile is failed, just ignore it. |
| 215 | 221 |
| 216 if (cancel_requested_) { | 222 if (cancel_requested_) { |
| 217 callback.Run(base::File::FILE_ERROR_ABORT); | 223 callback.Run(base::File::FILE_ERROR_ABORT); |
| 218 return; | 224 return; |
| 219 } | 225 } |
| 220 | 226 |
| 221 // |validator_| is NULL when the destination filesystem does not do | 227 // |validator_| is NULL when the destination filesystem does not do |
| 222 // validation. | 228 // validation. |
| 223 if (!validator_) { | 229 if (!validator_) { |
| 224 // No validation is needed. | 230 // No validation is needed. |
| 225 RunAfterPostWriteValidation(callback, base::File::FILE_OK); | 231 RunAfterPostWriteValidation(callback, base::File::FILE_OK); |
| 226 return; | 232 return; |
| 227 } | 233 } |
| 228 | 234 |
| 229 PostWriteValidation( | 235 PostWriteValidation( |
| 230 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPostWriteValidation, | 236 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterPostWriteValidation, |
| 231 weak_factory_.GetWeakPtr(), callback)); | 237 weak_factory_.GetWeakPtr(), |
| 238 callback)); |
| 232 } | 239 } |
| 233 | 240 |
| 234 void RunAfterPostWriteValidation( | 241 void RunAfterPostWriteValidation( |
| 235 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 242 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 236 base::File::Error error) { | 243 base::File::Error error) { |
| 237 if (cancel_requested_) { | 244 if (cancel_requested_) { |
| 238 callback.Run(base::File::FILE_ERROR_ABORT); | 245 callback.Run(base::File::FILE_ERROR_ABORT); |
| 239 return; | 246 return; |
| 240 } | 247 } |
| 241 | 248 |
| 242 if (error != base::File::FILE_OK) { | 249 if (error != base::File::FILE_OK) { |
| 243 // Failed to validate. Remove the destination file. | 250 // Failed to validate. Remove the destination file. |
| 244 operation_runner_->Remove( | 251 operation_runner_->Remove( |
| 245 dest_url_, true /* recursive */, | 252 dest_url_, |
| 253 true /* recursive */, |
| 246 base::Bind(&SnapshotCopyOrMoveImpl::DidRemoveDestForError, | 254 base::Bind(&SnapshotCopyOrMoveImpl::DidRemoveDestForError, |
| 247 weak_factory_.GetWeakPtr(), error, callback)); | 255 weak_factory_.GetWeakPtr(), |
| 256 error, |
| 257 callback)); |
| 248 return; | 258 return; |
| 249 } | 259 } |
| 250 | 260 |
| 251 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { | 261 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { |
| 252 callback.Run(base::File::FILE_OK); | 262 callback.Run(base::File::FILE_OK); |
| 253 return; | 263 return; |
| 254 } | 264 } |
| 255 | 265 |
| 256 DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); | 266 DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); |
| 257 | 267 |
| 258 // Remove the source for finalizing move operation. | 268 // Remove the source for finalizing move operation. |
| 259 operation_runner_->Remove( | 269 operation_runner_->Remove( |
| 260 src_url_, true /* recursive */, | 270 src_url_, |
| 271 true /* recursive */, |
| 261 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterRemoveSourceForMove, | 272 base::Bind(&SnapshotCopyOrMoveImpl::RunAfterRemoveSourceForMove, |
| 262 weak_factory_.GetWeakPtr(), callback)); | 273 weak_factory_.GetWeakPtr(), |
| 274 callback)); |
| 263 } | 275 } |
| 264 | 276 |
| 265 void RunAfterRemoveSourceForMove( | 277 void RunAfterRemoveSourceForMove( |
| 266 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 278 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 267 base::File::Error error) { | 279 base::File::Error error) { |
| 268 if (cancel_requested_) | 280 if (cancel_requested_) |
| 269 error = base::File::FILE_ERROR_ABORT; | 281 error = base::File::FILE_ERROR_ABORT; |
| 270 | 282 |
| 271 if (error == base::File::FILE_ERROR_NOT_FOUND) | 283 if (error == base::File::FILE_ERROR_NOT_FOUND) |
| 272 error = base::File::FILE_OK; | 284 error = base::File::FILE_OK; |
| 273 callback.Run(error); | 285 callback.Run(error); |
| 274 } | 286 } |
| 275 | 287 |
| 276 void DidRemoveDestForError( | 288 void DidRemoveDestForError( |
| 277 base::File::Error prior_error, | 289 base::File::Error prior_error, |
| 278 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 290 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 279 base::File::Error error) { | 291 base::File::Error error) { |
| 280 if (error != base::File::FILE_OK) { | 292 if (error != base::File::FILE_OK) { |
| 281 VLOG(1) << "Error removing destination file after validation error: " | 293 VLOG(1) << "Error removing destination file after validation error: " |
| 282 << error; | 294 << error; |
| 283 } | 295 } |
| 284 callback.Run(prior_error); | 296 callback.Run(prior_error); |
| 285 } | 297 } |
| 286 | 298 |
| 287 // Runs pre-write validation. | 299 // Runs pre-write validation. |
| 288 void PreWriteValidation( | 300 void PreWriteValidation( |
| 289 const base::FilePath& platform_path, | 301 const base::FilePath& platform_path, |
| 290 const CopyOrMoveOperationDelegate::StatusCallback& callback) { | 302 const CopyOrMoveOperationDelegate::StatusCallback& callback) { |
| 291 DCHECK(validator_factory_); | 303 DCHECK(validator_factory_); |
| 292 validator_.reset( | 304 validator_.reset(validator_factory_->CreateCopyOrMoveFileValidator( |
| 293 validator_factory_->CreateCopyOrMoveFileValidator( | 305 src_url_, platform_path)); |
| 294 src_url_, platform_path)); | |
| 295 validator_->StartPreWriteValidation(callback); | 306 validator_->StartPreWriteValidation(callback); |
| 296 } | 307 } |
| 297 | 308 |
| 298 // Runs post-write validation. | 309 // Runs post-write validation. |
| 299 void PostWriteValidation( | 310 void PostWriteValidation( |
| 300 const CopyOrMoveOperationDelegate::StatusCallback& callback) { | 311 const CopyOrMoveOperationDelegate::StatusCallback& callback) { |
| 301 operation_runner_->CreateSnapshotFile( | 312 operation_runner_->CreateSnapshotFile( |
| 302 dest_url_, | 313 dest_url_, |
| 303 base::Bind( | 314 base::Bind( |
| 304 &SnapshotCopyOrMoveImpl::PostWriteValidationAfterCreateSnapshotFile, | 315 &SnapshotCopyOrMoveImpl::PostWriteValidationAfterCreateSnapshotFile, |
| 305 weak_factory_.GetWeakPtr(), callback)); | 316 weak_factory_.GetWeakPtr(), |
| 317 callback)); |
| 306 } | 318 } |
| 307 | 319 |
| 308 void PostWriteValidationAfterCreateSnapshotFile( | 320 void PostWriteValidationAfterCreateSnapshotFile( |
| 309 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 321 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 310 base::File::Error error, | 322 base::File::Error error, |
| 311 const base::File::Info& file_info, | 323 const base::File::Info& file_info, |
| 312 const base::FilePath& platform_path, | 324 const base::FilePath& platform_path, |
| 313 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) { | 325 const scoped_refptr<storage::ShareableFileReference>& file_ref) { |
| 314 if (cancel_requested_) | 326 if (cancel_requested_) |
| 315 error = base::File::FILE_ERROR_ABORT; | 327 error = base::File::FILE_ERROR_ABORT; |
| 316 | 328 |
| 317 if (error != base::File::FILE_OK) { | 329 if (error != base::File::FILE_OK) { |
| 318 callback.Run(error); | 330 callback.Run(error); |
| 319 return; | 331 return; |
| 320 } | 332 } |
| 321 | 333 |
| 322 DCHECK(validator_); | 334 DCHECK(validator_); |
| 323 // Note: file_ref passed here to keep the file alive until after | 335 // Note: file_ref passed here to keep the file alive until after |
| 324 // the StartPostWriteValidation operation finishes. | 336 // the StartPostWriteValidation operation finishes. |
| 325 validator_->StartPostWriteValidation( | 337 validator_->StartPostWriteValidation( |
| 326 platform_path, | 338 platform_path, |
| 327 base::Bind(&SnapshotCopyOrMoveImpl::DidPostWriteValidation, | 339 base::Bind(&SnapshotCopyOrMoveImpl::DidPostWriteValidation, |
| 328 weak_factory_.GetWeakPtr(), file_ref, callback)); | 340 weak_factory_.GetWeakPtr(), |
| 341 file_ref, |
| 342 callback)); |
| 329 } | 343 } |
| 330 | 344 |
| 331 // |file_ref| is unused; it is passed here to make sure the reference is | 345 // |file_ref| is unused; it is passed here to make sure the reference is |
| 332 // alive until after post-write validation is complete. | 346 // alive until after post-write validation is complete. |
| 333 void DidPostWriteValidation( | 347 void DidPostWriteValidation( |
| 334 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref, | 348 const scoped_refptr<storage::ShareableFileReference>& file_ref, |
| 335 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 349 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 336 base::File::Error error) { | 350 base::File::Error error) { |
| 337 callback.Run(error); | 351 callback.Run(error); |
| 338 } | 352 } |
| 339 | 353 |
| 340 FileSystemOperationRunner* operation_runner_; | 354 FileSystemOperationRunner* operation_runner_; |
| 341 CopyOrMoveOperationDelegate::OperationType operation_type_; | 355 CopyOrMoveOperationDelegate::OperationType operation_type_; |
| 342 FileSystemURL src_url_; | 356 FileSystemURL src_url_; |
| 343 FileSystemURL dest_url_; | 357 FileSystemURL dest_url_; |
| 344 | 358 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 363 // necessary SnapshotCopyOrMoveImpl should be used. | 377 // necessary SnapshotCopyOrMoveImpl should be used. |
| 364 class StreamCopyOrMoveImpl | 378 class StreamCopyOrMoveImpl |
| 365 : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { | 379 : public CopyOrMoveOperationDelegate::CopyOrMoveImpl { |
| 366 public: | 380 public: |
| 367 StreamCopyOrMoveImpl( | 381 StreamCopyOrMoveImpl( |
| 368 FileSystemOperationRunner* operation_runner, | 382 FileSystemOperationRunner* operation_runner, |
| 369 CopyOrMoveOperationDelegate::OperationType operation_type, | 383 CopyOrMoveOperationDelegate::OperationType operation_type, |
| 370 const FileSystemURL& src_url, | 384 const FileSystemURL& src_url, |
| 371 const FileSystemURL& dest_url, | 385 const FileSystemURL& dest_url, |
| 372 CopyOrMoveOperationDelegate::CopyOrMoveOption option, | 386 CopyOrMoveOperationDelegate::CopyOrMoveOption option, |
| 373 scoped_ptr<webkit_blob::FileStreamReader> reader, | 387 scoped_ptr<storage::FileStreamReader> reader, |
| 374 scoped_ptr<FileStreamWriter> writer, | 388 scoped_ptr<FileStreamWriter> writer, |
| 375 const FileSystemOperation::CopyFileProgressCallback& | 389 const FileSystemOperation::CopyFileProgressCallback& |
| 376 file_progress_callback) | 390 file_progress_callback) |
| 377 : operation_runner_(operation_runner), | 391 : operation_runner_(operation_runner), |
| 378 operation_type_(operation_type), | 392 operation_type_(operation_type), |
| 379 src_url_(src_url), | 393 src_url_(src_url), |
| 380 dest_url_(dest_url), | 394 dest_url_(dest_url), |
| 381 option_(option), | 395 option_(option), |
| 382 reader_(reader.Pass()), | 396 reader_(reader.Pass()), |
| 383 writer_(writer.Pass()), | 397 writer_(writer.Pass()), |
| 384 file_progress_callback_(file_progress_callback), | 398 file_progress_callback_(file_progress_callback), |
| 385 cancel_requested_(false), | 399 cancel_requested_(false), |
| 386 weak_factory_(this) { | 400 weak_factory_(this) {} |
| 387 } | |
| 388 | 401 |
| 389 virtual void Run( | 402 virtual void Run( |
| 390 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { | 403 const CopyOrMoveOperationDelegate::StatusCallback& callback) OVERRIDE { |
| 391 // Reader can be created even if the entry does not exist or the entry is | 404 // Reader can be created even if the entry does not exist or the entry is |
| 392 // a directory. To check errors before destination file creation, | 405 // a directory. To check errors before destination file creation, |
| 393 // check metadata first. | 406 // check metadata first. |
| 394 operation_runner_->GetMetadata( | 407 operation_runner_->GetMetadata( |
| 395 src_url_, | 408 src_url_, |
| 396 base::Bind(&StreamCopyOrMoveImpl::RunAfterGetMetadataForSource, | 409 base::Bind(&StreamCopyOrMoveImpl::RunAfterGetMetadataForSource, |
| 397 weak_factory_.GetWeakPtr(), callback)); | 410 weak_factory_.GetWeakPtr(), |
| 411 callback)); |
| 398 } | 412 } |
| 399 | 413 |
| 400 virtual void Cancel() OVERRIDE { | 414 virtual void Cancel() OVERRIDE { |
| 401 cancel_requested_ = true; | 415 cancel_requested_ = true; |
| 402 if (copy_helper_) | 416 if (copy_helper_) |
| 403 copy_helper_->Cancel(); | 417 copy_helper_->Cancel(); |
| 404 } | 418 } |
| 405 | 419 |
| 406 private: | 420 private: |
| 407 void RunAfterGetMetadataForSource( | 421 void RunAfterGetMetadataForSource( |
| 408 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 422 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 409 base::File::Error error, | 423 base::File::Error error, |
| 410 const base::File::Info& file_info) { | 424 const base::File::Info& file_info) { |
| 411 if (cancel_requested_) | 425 if (cancel_requested_) |
| 412 error = base::File::FILE_ERROR_ABORT; | 426 error = base::File::FILE_ERROR_ABORT; |
| 413 | 427 |
| 414 if (error != base::File::FILE_OK) { | 428 if (error != base::File::FILE_OK) { |
| 415 callback.Run(error); | 429 callback.Run(error); |
| 416 return; | 430 return; |
| 417 } | 431 } |
| 418 | 432 |
| 419 if (file_info.is_directory) { | 433 if (file_info.is_directory) { |
| 420 // If not a directory, failed with appropriate error code. | 434 // If not a directory, failed with appropriate error code. |
| 421 callback.Run(base::File::FILE_ERROR_NOT_A_FILE); | 435 callback.Run(base::File::FILE_ERROR_NOT_A_FILE); |
| 422 return; | 436 return; |
| 423 } | 437 } |
| 424 | 438 |
| 425 // To use FileStreamWriter, we need to ensure the destination file exists. | 439 // To use FileStreamWriter, we need to ensure the destination file exists. |
| 426 operation_runner_->CreateFile( | 440 operation_runner_->CreateFile( |
| 427 dest_url_, false /* exclusive */, | 441 dest_url_, |
| 442 false /* exclusive */, |
| 428 base::Bind(&StreamCopyOrMoveImpl::RunAfterCreateFileForDestination, | 443 base::Bind(&StreamCopyOrMoveImpl::RunAfterCreateFileForDestination, |
| 429 weak_factory_.GetWeakPtr(), | 444 weak_factory_.GetWeakPtr(), |
| 430 callback, file_info.last_modified)); | 445 callback, |
| 446 file_info.last_modified)); |
| 431 } | 447 } |
| 432 | 448 |
| 433 void RunAfterCreateFileForDestination( | 449 void RunAfterCreateFileForDestination( |
| 434 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 450 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 435 const base::Time& last_modified, | 451 const base::Time& last_modified, |
| 436 base::File::Error error) { | 452 base::File::Error error) { |
| 437 if (cancel_requested_) | 453 if (cancel_requested_) |
| 438 error = base::File::FILE_ERROR_ABORT; | 454 error = base::File::FILE_ERROR_ABORT; |
| 439 | 455 |
| 440 if (error != base::File::FILE_OK) { | 456 if (error != base::File::FILE_OK) { |
| 441 callback.Run(error); | 457 callback.Run(error); |
| 442 return; | 458 return; |
| 443 } | 459 } |
| 444 | 460 |
| 445 const bool need_flush = dest_url_.mount_option().copy_sync_option() == | 461 const bool need_flush = dest_url_.mount_option().copy_sync_option() == |
| 446 fileapi::COPY_SYNC_OPTION_SYNC; | 462 storage::COPY_SYNC_OPTION_SYNC; |
| 447 | 463 |
| 448 DCHECK(!copy_helper_); | 464 DCHECK(!copy_helper_); |
| 449 copy_helper_.reset( | 465 copy_helper_.reset(new CopyOrMoveOperationDelegate::StreamCopyHelper( |
| 450 new CopyOrMoveOperationDelegate::StreamCopyHelper( | 466 reader_.Pass(), |
| 451 reader_.Pass(), writer_.Pass(), | 467 writer_.Pass(), |
| 452 need_flush, | 468 need_flush, |
| 453 kReadBufferSize, | 469 kReadBufferSize, |
| 454 file_progress_callback_, | 470 file_progress_callback_, |
| 455 base::TimeDelta::FromMilliseconds( | 471 base::TimeDelta::FromMilliseconds( |
| 456 kMinProgressCallbackInvocationSpanInMilliseconds))); | 472 kMinProgressCallbackInvocationSpanInMilliseconds))); |
| 457 copy_helper_->Run( | 473 copy_helper_->Run(base::Bind(&StreamCopyOrMoveImpl::RunAfterStreamCopy, |
| 458 base::Bind(&StreamCopyOrMoveImpl::RunAfterStreamCopy, | 474 weak_factory_.GetWeakPtr(), |
| 459 weak_factory_.GetWeakPtr(), callback, last_modified)); | 475 callback, |
| 476 last_modified)); |
| 460 } | 477 } |
| 461 | 478 |
| 462 void RunAfterStreamCopy( | 479 void RunAfterStreamCopy( |
| 463 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 480 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 464 const base::Time& last_modified, | 481 const base::Time& last_modified, |
| 465 base::File::Error error) { | 482 base::File::Error error) { |
| 466 if (cancel_requested_) | 483 if (cancel_requested_) |
| 467 error = base::File::FILE_ERROR_ABORT; | 484 error = base::File::FILE_ERROR_ABORT; |
| 468 | 485 |
| 469 if (error != base::File::FILE_OK) { | 486 if (error != base::File::FILE_OK) { |
| 470 callback.Run(error); | 487 callback.Run(error); |
| 471 return; | 488 return; |
| 472 } | 489 } |
| 473 | 490 |
| 474 if (option_ == FileSystemOperation::OPTION_NONE) { | 491 if (option_ == FileSystemOperation::OPTION_NONE) { |
| 475 RunAfterTouchFile(callback, base::File::FILE_OK); | 492 RunAfterTouchFile(callback, base::File::FILE_OK); |
| 476 return; | 493 return; |
| 477 } | 494 } |
| 478 | 495 |
| 479 operation_runner_->TouchFile( | 496 operation_runner_->TouchFile( |
| 480 dest_url_, base::Time::Now() /* last_access */, last_modified, | 497 dest_url_, |
| 498 base::Time::Now() /* last_access */, |
| 499 last_modified, |
| 481 base::Bind(&StreamCopyOrMoveImpl::RunAfterTouchFile, | 500 base::Bind(&StreamCopyOrMoveImpl::RunAfterTouchFile, |
| 482 weak_factory_.GetWeakPtr(), callback)); | 501 weak_factory_.GetWeakPtr(), |
| 502 callback)); |
| 483 } | 503 } |
| 484 | 504 |
| 485 void RunAfterTouchFile( | 505 void RunAfterTouchFile( |
| 486 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 506 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 487 base::File::Error error) { | 507 base::File::Error error) { |
| 488 // Even if TouchFile is failed, just ignore it. | 508 // Even if TouchFile is failed, just ignore it. |
| 489 if (cancel_requested_) { | 509 if (cancel_requested_) { |
| 490 callback.Run(base::File::FILE_ERROR_ABORT); | 510 callback.Run(base::File::FILE_ERROR_ABORT); |
| 491 return; | 511 return; |
| 492 } | 512 } |
| 493 | 513 |
| 494 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { | 514 if (operation_type_ == CopyOrMoveOperationDelegate::OPERATION_COPY) { |
| 495 callback.Run(base::File::FILE_OK); | 515 callback.Run(base::File::FILE_OK); |
| 496 return; | 516 return; |
| 497 } | 517 } |
| 498 | 518 |
| 499 DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); | 519 DCHECK_EQ(CopyOrMoveOperationDelegate::OPERATION_MOVE, operation_type_); |
| 500 | 520 |
| 501 // Remove the source for finalizing move operation. | 521 // Remove the source for finalizing move operation. |
| 502 operation_runner_->Remove( | 522 operation_runner_->Remove( |
| 503 src_url_, false /* recursive */, | 523 src_url_, |
| 524 false /* recursive */, |
| 504 base::Bind(&StreamCopyOrMoveImpl::RunAfterRemoveForMove, | 525 base::Bind(&StreamCopyOrMoveImpl::RunAfterRemoveForMove, |
| 505 weak_factory_.GetWeakPtr(), callback)); | 526 weak_factory_.GetWeakPtr(), |
| 527 callback)); |
| 506 } | 528 } |
| 507 | 529 |
| 508 void RunAfterRemoveForMove( | 530 void RunAfterRemoveForMove( |
| 509 const CopyOrMoveOperationDelegate::StatusCallback& callback, | 531 const CopyOrMoveOperationDelegate::StatusCallback& callback, |
| 510 base::File::Error error) { | 532 base::File::Error error) { |
| 511 if (cancel_requested_) | 533 if (cancel_requested_) |
| 512 error = base::File::FILE_ERROR_ABORT; | 534 error = base::File::FILE_ERROR_ABORT; |
| 513 if (error == base::File::FILE_ERROR_NOT_FOUND) | 535 if (error == base::File::FILE_ERROR_NOT_FOUND) |
| 514 error = base::File::FILE_OK; | 536 error = base::File::FILE_OK; |
| 515 callback.Run(error); | 537 callback.Run(error); |
| 516 } | 538 } |
| 517 | 539 |
| 518 FileSystemOperationRunner* operation_runner_; | 540 FileSystemOperationRunner* operation_runner_; |
| 519 CopyOrMoveOperationDelegate::OperationType operation_type_; | 541 CopyOrMoveOperationDelegate::OperationType operation_type_; |
| 520 FileSystemURL src_url_; | 542 FileSystemURL src_url_; |
| 521 FileSystemURL dest_url_; | 543 FileSystemURL dest_url_; |
| 522 CopyOrMoveOperationDelegate::CopyOrMoveOption option_; | 544 CopyOrMoveOperationDelegate::CopyOrMoveOption option_; |
| 523 scoped_ptr<webkit_blob::FileStreamReader> reader_; | 545 scoped_ptr<storage::FileStreamReader> reader_; |
| 524 scoped_ptr<FileStreamWriter> writer_; | 546 scoped_ptr<FileStreamWriter> writer_; |
| 525 FileSystemOperation::CopyFileProgressCallback file_progress_callback_; | 547 FileSystemOperation::CopyFileProgressCallback file_progress_callback_; |
| 526 scoped_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; | 548 scoped_ptr<CopyOrMoveOperationDelegate::StreamCopyHelper> copy_helper_; |
| 527 bool cancel_requested_; | 549 bool cancel_requested_; |
| 528 base::WeakPtrFactory<StreamCopyOrMoveImpl> weak_factory_; | 550 base::WeakPtrFactory<StreamCopyOrMoveImpl> weak_factory_; |
| 529 DISALLOW_COPY_AND_ASSIGN(StreamCopyOrMoveImpl); | 551 DISALLOW_COPY_AND_ASSIGN(StreamCopyOrMoveImpl); |
| 530 }; | 552 }; |
| 531 | 553 |
| 532 } // namespace | 554 } // namespace |
| 533 | 555 |
| 534 CopyOrMoveOperationDelegate::StreamCopyHelper::StreamCopyHelper( | 556 CopyOrMoveOperationDelegate::StreamCopyHelper::StreamCopyHelper( |
| 535 scoped_ptr<webkit_blob::FileStreamReader> reader, | 557 scoped_ptr<storage::FileStreamReader> reader, |
| 536 scoped_ptr<FileStreamWriter> writer, | 558 scoped_ptr<FileStreamWriter> writer, |
| 537 bool need_flush, | 559 bool need_flush, |
| 538 int buffer_size, | 560 int buffer_size, |
| 539 const FileSystemOperation::CopyFileProgressCallback& | 561 const FileSystemOperation::CopyFileProgressCallback& file_progress_callback, |
| 540 file_progress_callback, | |
| 541 const base::TimeDelta& min_progress_callback_invocation_span) | 562 const base::TimeDelta& min_progress_callback_invocation_span) |
| 542 : reader_(reader.Pass()), | 563 : reader_(reader.Pass()), |
| 543 writer_(writer.Pass()), | 564 writer_(writer.Pass()), |
| 544 need_flush_(need_flush), | 565 need_flush_(need_flush), |
| 545 file_progress_callback_(file_progress_callback), | 566 file_progress_callback_(file_progress_callback), |
| 546 io_buffer_(new net::IOBufferWithSize(buffer_size)), | 567 io_buffer_(new net::IOBufferWithSize(buffer_size)), |
| 547 num_copied_bytes_(0), | 568 num_copied_bytes_(0), |
| 548 previous_flush_offset_(0), | 569 previous_flush_offset_(0), |
| 549 min_progress_callback_invocation_span_( | 570 min_progress_callback_invocation_span_( |
| 550 min_progress_callback_invocation_span), | 571 min_progress_callback_invocation_span), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 562 Read(callback); | 583 Read(callback); |
| 563 } | 584 } |
| 564 | 585 |
| 565 void CopyOrMoveOperationDelegate::StreamCopyHelper::Cancel() { | 586 void CopyOrMoveOperationDelegate::StreamCopyHelper::Cancel() { |
| 566 cancel_requested_ = true; | 587 cancel_requested_ = true; |
| 567 } | 588 } |
| 568 | 589 |
| 569 void CopyOrMoveOperationDelegate::StreamCopyHelper::Read( | 590 void CopyOrMoveOperationDelegate::StreamCopyHelper::Read( |
| 570 const StatusCallback& callback) { | 591 const StatusCallback& callback) { |
| 571 int result = reader_->Read( | 592 int result = reader_->Read( |
| 572 io_buffer_.get(), io_buffer_->size(), | 593 io_buffer_.get(), |
| 573 base::Bind(&StreamCopyHelper::DidRead, | 594 io_buffer_->size(), |
| 574 weak_factory_.GetWeakPtr(), callback)); | 595 base::Bind( |
| 596 &StreamCopyHelper::DidRead, weak_factory_.GetWeakPtr(), callback)); |
| 575 if (result != net::ERR_IO_PENDING) | 597 if (result != net::ERR_IO_PENDING) |
| 576 DidRead(callback, result); | 598 DidRead(callback, result); |
| 577 } | 599 } |
| 578 | 600 |
| 579 void CopyOrMoveOperationDelegate::StreamCopyHelper::DidRead( | 601 void CopyOrMoveOperationDelegate::StreamCopyHelper::DidRead( |
| 580 const StatusCallback& callback, int result) { | 602 const StatusCallback& callback, |
| 603 int result) { |
| 581 if (cancel_requested_) { | 604 if (cancel_requested_) { |
| 582 callback.Run(base::File::FILE_ERROR_ABORT); | 605 callback.Run(base::File::FILE_ERROR_ABORT); |
| 583 return; | 606 return; |
| 584 } | 607 } |
| 585 | 608 |
| 586 if (result < 0) { | 609 if (result < 0) { |
| 587 callback.Run(NetErrorToFileError(result)); | 610 callback.Run(NetErrorToFileError(result)); |
| 588 return; | 611 return; |
| 589 } | 612 } |
| 590 | 613 |
| 591 if (result == 0) { | 614 if (result == 0) { |
| 592 // Here is the EOF. | 615 // Here is the EOF. |
| 593 if (need_flush_) | 616 if (need_flush_) |
| 594 Flush(callback, true /* is_eof */); | 617 Flush(callback, true /* is_eof */); |
| 595 else | 618 else |
| 596 callback.Run(base::File::FILE_OK); | 619 callback.Run(base::File::FILE_OK); |
| 597 return; | 620 return; |
| 598 } | 621 } |
| 599 | 622 |
| 600 Write(callback, new net::DrainableIOBuffer(io_buffer_.get(), result)); | 623 Write(callback, new net::DrainableIOBuffer(io_buffer_.get(), result)); |
| 601 } | 624 } |
| 602 | 625 |
| 603 void CopyOrMoveOperationDelegate::StreamCopyHelper::Write( | 626 void CopyOrMoveOperationDelegate::StreamCopyHelper::Write( |
| 604 const StatusCallback& callback, | 627 const StatusCallback& callback, |
| 605 scoped_refptr<net::DrainableIOBuffer> buffer) { | 628 scoped_refptr<net::DrainableIOBuffer> buffer) { |
| 606 DCHECK_GT(buffer->BytesRemaining(), 0); | 629 DCHECK_GT(buffer->BytesRemaining(), 0); |
| 607 | 630 |
| 608 int result = writer_->Write( | 631 int result = writer_->Write(buffer.get(), |
| 609 buffer.get(), buffer->BytesRemaining(), | 632 buffer->BytesRemaining(), |
| 610 base::Bind(&StreamCopyHelper::DidWrite, | 633 base::Bind(&StreamCopyHelper::DidWrite, |
| 611 weak_factory_.GetWeakPtr(), callback, buffer)); | 634 weak_factory_.GetWeakPtr(), |
| 635 callback, |
| 636 buffer)); |
| 612 if (result != net::ERR_IO_PENDING) | 637 if (result != net::ERR_IO_PENDING) |
| 613 DidWrite(callback, buffer, result); | 638 DidWrite(callback, buffer, result); |
| 614 } | 639 } |
| 615 | 640 |
| 616 void CopyOrMoveOperationDelegate::StreamCopyHelper::DidWrite( | 641 void CopyOrMoveOperationDelegate::StreamCopyHelper::DidWrite( |
| 617 const StatusCallback& callback, | 642 const StatusCallback& callback, |
| 618 scoped_refptr<net::DrainableIOBuffer> buffer, | 643 scoped_refptr<net::DrainableIOBuffer> buffer, |
| 619 int result) { | 644 int result) { |
| 620 if (cancel_requested_) { | 645 if (cancel_requested_) { |
| 621 callback.Run(base::File::FILE_ERROR_ABORT); | 646 callback.Run(base::File::FILE_ERROR_ABORT); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 645 | 670 |
| 646 if (need_flush_ && | 671 if (need_flush_ && |
| 647 (num_copied_bytes_ - previous_flush_offset_) > kFlushIntervalInBytes) { | 672 (num_copied_bytes_ - previous_flush_offset_) > kFlushIntervalInBytes) { |
| 648 Flush(callback, false /* not is_eof */); | 673 Flush(callback, false /* not is_eof */); |
| 649 } else { | 674 } else { |
| 650 Read(callback); | 675 Read(callback); |
| 651 } | 676 } |
| 652 } | 677 } |
| 653 | 678 |
| 654 void CopyOrMoveOperationDelegate::StreamCopyHelper::Flush( | 679 void CopyOrMoveOperationDelegate::StreamCopyHelper::Flush( |
| 655 const StatusCallback& callback, bool is_eof) { | 680 const StatusCallback& callback, |
| 656 int result = writer_->Flush( | 681 bool is_eof) { |
| 657 base::Bind(&StreamCopyHelper::DidFlush, | 682 int result = writer_->Flush(base::Bind(&StreamCopyHelper::DidFlush, |
| 658 weak_factory_.GetWeakPtr(), callback, is_eof)); | 683 weak_factory_.GetWeakPtr(), |
| 684 callback, |
| 685 is_eof)); |
| 659 if (result != net::ERR_IO_PENDING) | 686 if (result != net::ERR_IO_PENDING) |
| 660 DidFlush(callback, is_eof, result); | 687 DidFlush(callback, is_eof, result); |
| 661 } | 688 } |
| 662 | 689 |
| 663 void CopyOrMoveOperationDelegate::StreamCopyHelper::DidFlush( | 690 void CopyOrMoveOperationDelegate::StreamCopyHelper::DidFlush( |
| 664 const StatusCallback& callback, bool is_eof, int result) { | 691 const StatusCallback& callback, |
| 692 bool is_eof, |
| 693 int result) { |
| 665 if (cancel_requested_) { | 694 if (cancel_requested_) { |
| 666 callback.Run(base::File::FILE_ERROR_ABORT); | 695 callback.Run(base::File::FILE_ERROR_ABORT); |
| 667 return; | 696 return; |
| 668 } | 697 } |
| 669 | 698 |
| 670 previous_flush_offset_ = num_copied_bytes_; | 699 previous_flush_offset_ = num_copied_bytes_; |
| 671 if (is_eof) | 700 if (is_eof) |
| 672 callback.Run(NetErrorToFileError(result)); | 701 callback.Run(NetErrorToFileError(result)); |
| 673 else | 702 else |
| 674 Read(callback); | 703 Read(callback); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 return; | 748 return; |
| 720 } | 749 } |
| 721 | 750 |
| 722 // Start to process the source directory recursively. | 751 // Start to process the source directory recursively. |
| 723 // TODO(kinuko): This could be too expensive for same_file_system_==true | 752 // TODO(kinuko): This could be too expensive for same_file_system_==true |
| 724 // and operation==MOVE case, probably we can just rename the root directory. | 753 // and operation==MOVE case, probably we can just rename the root directory. |
| 725 // http://crbug.com/172187 | 754 // http://crbug.com/172187 |
| 726 StartRecursiveOperation(src_root_, callback_); | 755 StartRecursiveOperation(src_root_, callback_); |
| 727 } | 756 } |
| 728 | 757 |
| 729 void CopyOrMoveOperationDelegate::ProcessFile( | 758 void CopyOrMoveOperationDelegate::ProcessFile(const FileSystemURL& src_url, |
| 730 const FileSystemURL& src_url, | 759 const StatusCallback& callback) { |
| 731 const StatusCallback& callback) { | |
| 732 if (!progress_callback_.is_null()) { | 760 if (!progress_callback_.is_null()) { |
| 733 progress_callback_.Run( | 761 progress_callback_.Run( |
| 734 FileSystemOperation::BEGIN_COPY_ENTRY, src_url, FileSystemURL(), 0); | 762 FileSystemOperation::BEGIN_COPY_ENTRY, src_url, FileSystemURL(), 0); |
| 735 } | 763 } |
| 736 | 764 |
| 737 FileSystemURL dest_url = CreateDestURL(src_url); | 765 FileSystemURL dest_url = CreateDestURL(src_url); |
| 738 CopyOrMoveImpl* impl = NULL; | 766 CopyOrMoveImpl* impl = NULL; |
| 739 if (same_file_system_) { | 767 if (same_file_system_) { |
| 740 impl = new CopyOrMoveOnSameFileSystemImpl( | 768 impl = new CopyOrMoveOnSameFileSystemImpl( |
| 741 operation_runner(), operation_type_, src_url, dest_url, option_, | 769 operation_runner(), |
| 770 operation_type_, |
| 771 src_url, |
| 772 dest_url, |
| 773 option_, |
| 742 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, | 774 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, |
| 743 weak_factory_.GetWeakPtr(), src_url)); | 775 weak_factory_.GetWeakPtr(), |
| 776 src_url)); |
| 744 } else { | 777 } else { |
| 745 // Cross filesystem case. | 778 // Cross filesystem case. |
| 746 base::File::Error error = base::File::FILE_ERROR_FAILED; | 779 base::File::Error error = base::File::FILE_ERROR_FAILED; |
| 747 CopyOrMoveFileValidatorFactory* validator_factory = | 780 CopyOrMoveFileValidatorFactory* validator_factory = |
| 748 file_system_context()->GetCopyOrMoveFileValidatorFactory( | 781 file_system_context()->GetCopyOrMoveFileValidatorFactory( |
| 749 dest_root_.type(), &error); | 782 dest_root_.type(), &error); |
| 750 if (error != base::File::FILE_OK) { | 783 if (error != base::File::FILE_OK) { |
| 751 callback.Run(error); | 784 callback.Run(error); |
| 752 return; | 785 return; |
| 753 } | 786 } |
| 754 | 787 |
| 755 if (!validator_factory) { | 788 if (!validator_factory) { |
| 756 scoped_ptr<webkit_blob::FileStreamReader> reader = | 789 scoped_ptr<storage::FileStreamReader> reader = |
| 757 file_system_context()->CreateFileStreamReader( | 790 file_system_context()->CreateFileStreamReader( |
| 758 src_url, 0, base::Time()); | 791 src_url, 0, base::Time()); |
| 759 scoped_ptr<FileStreamWriter> writer = | 792 scoped_ptr<FileStreamWriter> writer = |
| 760 file_system_context()->CreateFileStreamWriter(dest_url, 0); | 793 file_system_context()->CreateFileStreamWriter(dest_url, 0); |
| 761 if (reader && writer) { | 794 if (reader && writer) { |
| 762 impl = new StreamCopyOrMoveImpl( | 795 impl = new StreamCopyOrMoveImpl( |
| 763 operation_runner(), operation_type_, src_url, dest_url, option_, | 796 operation_runner(), |
| 764 reader.Pass(), writer.Pass(), | 797 operation_type_, |
| 798 src_url, |
| 799 dest_url, |
| 800 option_, |
| 801 reader.Pass(), |
| 802 writer.Pass(), |
| 765 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, | 803 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, |
| 766 weak_factory_.GetWeakPtr(), src_url)); | 804 weak_factory_.GetWeakPtr(), |
| 805 src_url)); |
| 767 } | 806 } |
| 768 } | 807 } |
| 769 | 808 |
| 770 if (!impl) { | 809 if (!impl) { |
| 771 impl = new SnapshotCopyOrMoveImpl( | 810 impl = new SnapshotCopyOrMoveImpl( |
| 772 operation_runner(), operation_type_, src_url, dest_url, option_, | 811 operation_runner(), |
| 812 operation_type_, |
| 813 src_url, |
| 814 dest_url, |
| 815 option_, |
| 773 validator_factory, | 816 validator_factory, |
| 774 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, | 817 base::Bind(&CopyOrMoveOperationDelegate::OnCopyFileProgress, |
| 775 weak_factory_.GetWeakPtr(), src_url)); | 818 weak_factory_.GetWeakPtr(), |
| 819 src_url)); |
| 776 } | 820 } |
| 777 } | 821 } |
| 778 | 822 |
| 779 // Register the running task. | 823 // Register the running task. |
| 780 running_copy_set_.insert(impl); | 824 running_copy_set_.insert(impl); |
| 781 impl->Run(base::Bind( | 825 impl->Run(base::Bind(&CopyOrMoveOperationDelegate::DidCopyOrMoveFile, |
| 782 &CopyOrMoveOperationDelegate::DidCopyOrMoveFile, | 826 weak_factory_.GetWeakPtr(), |
| 783 weak_factory_.GetWeakPtr(), src_url, dest_url, callback, impl)); | 827 src_url, |
| 828 dest_url, |
| 829 callback, |
| 830 impl)); |
| 784 } | 831 } |
| 785 | 832 |
| 786 void CopyOrMoveOperationDelegate::ProcessDirectory( | 833 void CopyOrMoveOperationDelegate::ProcessDirectory( |
| 787 const FileSystemURL& src_url, | 834 const FileSystemURL& src_url, |
| 788 const StatusCallback& callback) { | 835 const StatusCallback& callback) { |
| 789 if (src_url == src_root_) { | 836 if (src_url == src_root_) { |
| 790 // The src_root_ looks to be a directory. | 837 // The src_root_ looks to be a directory. |
| 791 // Try removing the dest_root_ to see if it exists and/or it is an | 838 // Try removing the dest_root_ to see if it exists and/or it is an |
| 792 // empty directory. | 839 // empty directory. |
| 793 // We do not invoke |progress_callback_| for source root, because it is | 840 // We do not invoke |progress_callback_| for source root, because it is |
| 794 // already called in ProcessFile(). | 841 // already called in ProcessFile(). |
| 795 operation_runner()->RemoveDirectory( | 842 operation_runner()->RemoveDirectory( |
| 796 dest_root_, | 843 dest_root_, |
| 797 base::Bind(&CopyOrMoveOperationDelegate::DidTryRemoveDestRoot, | 844 base::Bind(&CopyOrMoveOperationDelegate::DidTryRemoveDestRoot, |
| 798 weak_factory_.GetWeakPtr(), callback)); | 845 weak_factory_.GetWeakPtr(), |
| 846 callback)); |
| 799 return; | 847 return; |
| 800 } | 848 } |
| 801 | 849 |
| 802 if (!progress_callback_.is_null()) { | 850 if (!progress_callback_.is_null()) { |
| 803 progress_callback_.Run( | 851 progress_callback_.Run( |
| 804 FileSystemOperation::BEGIN_COPY_ENTRY, src_url, FileSystemURL(), 0); | 852 FileSystemOperation::BEGIN_COPY_ENTRY, src_url, FileSystemURL(), 0); |
| 805 } | 853 } |
| 806 | 854 |
| 807 ProcessDirectoryInternal(src_url, CreateDestURL(src_url), callback); | 855 ProcessDirectoryInternal(src_url, CreateDestURL(src_url), callback); |
| 808 } | 856 } |
| 809 | 857 |
| 810 void CopyOrMoveOperationDelegate::PostProcessDirectory( | 858 void CopyOrMoveOperationDelegate::PostProcessDirectory( |
| 811 const FileSystemURL& src_url, | 859 const FileSystemURL& src_url, |
| 812 const StatusCallback& callback) { | 860 const StatusCallback& callback) { |
| 813 if (option_ == FileSystemOperation::OPTION_NONE) { | 861 if (option_ == FileSystemOperation::OPTION_NONE) { |
| 814 PostProcessDirectoryAfterTouchFile( | 862 PostProcessDirectoryAfterTouchFile(src_url, callback, base::File::FILE_OK); |
| 815 src_url, callback, base::File::FILE_OK); | |
| 816 return; | 863 return; |
| 817 } | 864 } |
| 818 | 865 |
| 819 operation_runner()->GetMetadata( | 866 operation_runner()->GetMetadata( |
| 820 src_url, | 867 src_url, |
| 821 base::Bind( | 868 base::Bind( |
| 822 &CopyOrMoveOperationDelegate::PostProcessDirectoryAfterGetMetadata, | 869 &CopyOrMoveOperationDelegate::PostProcessDirectoryAfterGetMetadata, |
| 823 weak_factory_.GetWeakPtr(), src_url, callback)); | 870 weak_factory_.GetWeakPtr(), |
| 871 src_url, |
| 872 callback)); |
| 824 } | 873 } |
| 825 | 874 |
| 826 void CopyOrMoveOperationDelegate::OnCancel() { | 875 void CopyOrMoveOperationDelegate::OnCancel() { |
| 827 // Request to cancel all running Copy/Move file. | 876 // Request to cancel all running Copy/Move file. |
| 828 for (std::set<CopyOrMoveImpl*>::iterator iter = running_copy_set_.begin(); | 877 for (std::set<CopyOrMoveImpl*>::iterator iter = running_copy_set_.begin(); |
| 829 iter != running_copy_set_.end(); ++iter) | 878 iter != running_copy_set_.end(); |
| 879 ++iter) |
| 830 (*iter)->Cancel(); | 880 (*iter)->Cancel(); |
| 831 } | 881 } |
| 832 | 882 |
| 833 void CopyOrMoveOperationDelegate::DidCopyOrMoveFile( | 883 void CopyOrMoveOperationDelegate::DidCopyOrMoveFile( |
| 834 const FileSystemURL& src_url, | 884 const FileSystemURL& src_url, |
| 835 const FileSystemURL& dest_url, | 885 const FileSystemURL& dest_url, |
| 836 const StatusCallback& callback, | 886 const StatusCallback& callback, |
| 837 CopyOrMoveImpl* impl, | 887 CopyOrMoveImpl* impl, |
| 838 base::File::Error error) { | 888 base::File::Error error) { |
| 839 running_copy_set_.erase(impl); | 889 running_copy_set_.erase(impl); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 865 | 915 |
| 866 void CopyOrMoveOperationDelegate::ProcessDirectoryInternal( | 916 void CopyOrMoveOperationDelegate::ProcessDirectoryInternal( |
| 867 const FileSystemURL& src_url, | 917 const FileSystemURL& src_url, |
| 868 const FileSystemURL& dest_url, | 918 const FileSystemURL& dest_url, |
| 869 const StatusCallback& callback) { | 919 const StatusCallback& callback) { |
| 870 // If operation_type == Move we may need to record directories and | 920 // If operation_type == Move we may need to record directories and |
| 871 // restore directory timestamps in the end, though it may have | 921 // restore directory timestamps in the end, though it may have |
| 872 // negative performance impact. | 922 // negative performance impact. |
| 873 // See http://crbug.com/171284 for more details. | 923 // See http://crbug.com/171284 for more details. |
| 874 operation_runner()->CreateDirectory( | 924 operation_runner()->CreateDirectory( |
| 875 dest_url, false /* exclusive */, false /* recursive */, | 925 dest_url, |
| 926 false /* exclusive */, |
| 927 false /* recursive */, |
| 876 base::Bind(&CopyOrMoveOperationDelegate::DidCreateDirectory, | 928 base::Bind(&CopyOrMoveOperationDelegate::DidCreateDirectory, |
| 877 weak_factory_.GetWeakPtr(), src_url, dest_url, callback)); | 929 weak_factory_.GetWeakPtr(), |
| 930 src_url, |
| 931 dest_url, |
| 932 callback)); |
| 878 } | 933 } |
| 879 | 934 |
| 880 void CopyOrMoveOperationDelegate::DidCreateDirectory( | 935 void CopyOrMoveOperationDelegate::DidCreateDirectory( |
| 881 const FileSystemURL& src_url, | 936 const FileSystemURL& src_url, |
| 882 const FileSystemURL& dest_url, | 937 const FileSystemURL& dest_url, |
| 883 const StatusCallback& callback, | 938 const StatusCallback& callback, |
| 884 base::File::Error error) { | 939 base::File::Error error) { |
| 885 if (!progress_callback_.is_null() && error == base::File::FILE_OK) { | 940 if (!progress_callback_.is_null() && error == base::File::FILE_OK) { |
| 886 progress_callback_.Run( | 941 progress_callback_.Run( |
| 887 FileSystemOperation::END_COPY_ENTRY, src_url, dest_url, 0); | 942 FileSystemOperation::END_COPY_ENTRY, src_url, dest_url, 0); |
| 888 } | 943 } |
| 889 | 944 |
| 890 callback.Run(error); | 945 callback.Run(error); |
| 891 } | 946 } |
| 892 | 947 |
| 893 void CopyOrMoveOperationDelegate::PostProcessDirectoryAfterGetMetadata( | 948 void CopyOrMoveOperationDelegate::PostProcessDirectoryAfterGetMetadata( |
| 894 const FileSystemURL& src_url, | 949 const FileSystemURL& src_url, |
| 895 const StatusCallback& callback, | 950 const StatusCallback& callback, |
| 896 base::File::Error error, | 951 base::File::Error error, |
| 897 const base::File::Info& file_info) { | 952 const base::File::Info& file_info) { |
| 898 if (error != base::File::FILE_OK) { | 953 if (error != base::File::FILE_OK) { |
| 899 // Ignore the error, and run post process which should run after TouchFile. | 954 // Ignore the error, and run post process which should run after TouchFile. |
| 900 PostProcessDirectoryAfterTouchFile( | 955 PostProcessDirectoryAfterTouchFile(src_url, callback, base::File::FILE_OK); |
| 901 src_url, callback, base::File::FILE_OK); | |
| 902 return; | 956 return; |
| 903 } | 957 } |
| 904 | 958 |
| 905 operation_runner()->TouchFile( | 959 operation_runner()->TouchFile( |
| 906 CreateDestURL(src_url), base::Time::Now() /* last access */, | 960 CreateDestURL(src_url), |
| 961 base::Time::Now() /* last access */, |
| 907 file_info.last_modified, | 962 file_info.last_modified, |
| 908 base::Bind( | 963 base::Bind( |
| 909 &CopyOrMoveOperationDelegate::PostProcessDirectoryAfterTouchFile, | 964 &CopyOrMoveOperationDelegate::PostProcessDirectoryAfterTouchFile, |
| 910 weak_factory_.GetWeakPtr(), src_url, callback)); | 965 weak_factory_.GetWeakPtr(), |
| 966 src_url, |
| 967 callback)); |
| 911 } | 968 } |
| 912 | 969 |
| 913 void CopyOrMoveOperationDelegate::PostProcessDirectoryAfterTouchFile( | 970 void CopyOrMoveOperationDelegate::PostProcessDirectoryAfterTouchFile( |
| 914 const FileSystemURL& src_url, | 971 const FileSystemURL& src_url, |
| 915 const StatusCallback& callback, | 972 const StatusCallback& callback, |
| 916 base::File::Error error) { | 973 base::File::Error error) { |
| 917 // Even if the TouchFile is failed, just ignore it. | 974 // Even if the TouchFile is failed, just ignore it. |
| 918 | 975 |
| 919 if (operation_type_ == OPERATION_COPY) { | 976 if (operation_type_ == OPERATION_COPY) { |
| 920 callback.Run(base::File::FILE_OK); | 977 callback.Run(base::File::FILE_OK); |
| 921 return; | 978 return; |
| 922 } | 979 } |
| 923 | 980 |
| 924 DCHECK_EQ(OPERATION_MOVE, operation_type_); | 981 DCHECK_EQ(OPERATION_MOVE, operation_type_); |
| 925 | 982 |
| 926 // All files and subdirectories in the directory should be moved here, | 983 // All files and subdirectories in the directory should be moved here, |
| 927 // so remove the source directory for finalizing move operation. | 984 // so remove the source directory for finalizing move operation. |
| 928 operation_runner()->Remove( | 985 operation_runner()->Remove( |
| 929 src_url, false /* recursive */, | 986 src_url, |
| 987 false /* recursive */, |
| 930 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, | 988 base::Bind(&CopyOrMoveOperationDelegate::DidRemoveSourceForMove, |
| 931 weak_factory_.GetWeakPtr(), callback)); | 989 weak_factory_.GetWeakPtr(), |
| 990 callback)); |
| 932 } | 991 } |
| 933 | 992 |
| 934 void CopyOrMoveOperationDelegate::DidRemoveSourceForMove( | 993 void CopyOrMoveOperationDelegate::DidRemoveSourceForMove( |
| 935 const StatusCallback& callback, | 994 const StatusCallback& callback, |
| 936 base::File::Error error) { | 995 base::File::Error error) { |
| 937 if (error == base::File::FILE_ERROR_NOT_FOUND) | 996 if (error == base::File::FILE_ERROR_NOT_FOUND) |
| 938 error = base::File::FILE_OK; | 997 error = base::File::FILE_OK; |
| 939 callback.Run(error); | 998 callback.Run(error); |
| 940 } | 999 } |
| 941 | 1000 |
| 942 void CopyOrMoveOperationDelegate::OnCopyFileProgress( | 1001 void CopyOrMoveOperationDelegate::OnCopyFileProgress( |
| 943 const FileSystemURL& src_url, int64 size) { | 1002 const FileSystemURL& src_url, |
| 1003 int64 size) { |
| 944 if (!progress_callback_.is_null()) { | 1004 if (!progress_callback_.is_null()) { |
| 945 progress_callback_.Run( | 1005 progress_callback_.Run( |
| 946 FileSystemOperation::PROGRESS, src_url, FileSystemURL(), size); | 1006 FileSystemOperation::PROGRESS, src_url, FileSystemURL(), size); |
| 947 } | 1007 } |
| 948 } | 1008 } |
| 949 | 1009 |
| 950 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( | 1010 FileSystemURL CopyOrMoveOperationDelegate::CreateDestURL( |
| 951 const FileSystemURL& src_url) const { | 1011 const FileSystemURL& src_url) const { |
| 952 DCHECK_EQ(src_root_.type(), src_url.type()); | 1012 DCHECK_EQ(src_root_.type(), src_url.type()); |
| 953 DCHECK_EQ(src_root_.origin(), src_url.origin()); | 1013 DCHECK_EQ(src_root_.origin(), src_url.origin()); |
| 954 | 1014 |
| 955 base::FilePath relative = dest_root_.virtual_path(); | 1015 base::FilePath relative = dest_root_.virtual_path(); |
| 956 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), | 1016 src_root_.virtual_path().AppendRelativePath(src_url.virtual_path(), |
| 957 &relative); | 1017 &relative); |
| 958 return file_system_context()->CreateCrackedFileSystemURL( | 1018 return file_system_context()->CreateCrackedFileSystemURL( |
| 959 dest_root_.origin(), | 1019 dest_root_.origin(), dest_root_.mount_type(), relative); |
| 960 dest_root_.mount_type(), | |
| 961 relative); | |
| 962 } | 1020 } |
| 963 | 1021 |
| 964 } // namespace fileapi | 1022 } // namespace storage |
| OLD | NEW |