| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/download/download_file_impl.h" | 5 #include "content/browser/download/download_file_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 bool is_sparse_file, | 64 bool is_sparse_file, |
| 65 base::WeakPtr<DownloadDestinationObserver> observer) | 65 base::WeakPtr<DownloadDestinationObserver> observer) |
| 66 : net_log_( | 66 : net_log_( |
| 67 net::NetLogWithSource::Make(download_item_net_log.net_log(), | 67 net::NetLogWithSource::Make(download_item_net_log.net_log(), |
| 68 net::NetLogSourceType::DOWNLOAD_FILE)), | 68 net::NetLogSourceType::DOWNLOAD_FILE)), |
| 69 file_(net_log_), | 69 file_(net_log_), |
| 70 save_info_(std::move(save_info)), | 70 save_info_(std::move(save_info)), |
| 71 default_download_directory_(default_download_directory), | 71 default_download_directory_(default_download_directory), |
| 72 is_sparse_file_(is_sparse_file), | 72 is_sparse_file_(is_sparse_file), |
| 73 bytes_seen_(0), | 73 bytes_seen_(0), |
| 74 num_active_streams_(0), |
| 75 bytes_seen_with_parallel_streams_(0), |
| 76 bytes_seen_without_parallel_streams_(0), |
| 74 received_slices_(received_slices), | 77 received_slices_(received_slices), |
| 75 observer_(observer), | 78 observer_(observer), |
| 76 weak_factory_(this) { | 79 weak_factory_(this) { |
| 77 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>( | 80 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>( |
| 78 save_info_->offset, DownloadSaveInfo::kLengthFullContent); | 81 save_info_->offset, DownloadSaveInfo::kLengthFullContent); |
| 79 DCHECK(source_streams_.size() == static_cast<size_t>(1)); | 82 DCHECK(source_streams_.size() == static_cast<size_t>(1)); |
| 80 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader)); | 83 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader)); |
| 81 | 84 |
| 82 download_item_net_log.AddEvent( | 85 download_item_net_log.AddEvent( |
| 83 net::NetLogEventType::DOWNLOAD_FILE_CREATED, | 86 net::NetLogEventType::DOWNLOAD_FILE_CREATED, |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 source_stream->bytes_written() + | 313 source_stream->bytes_written() + |
| 311 static_cast<int64_t>(incoming_data_size) >= | 314 static_cast<int64_t>(incoming_data_size) >= |
| 312 source_stream->length()) { | 315 source_stream->length()) { |
| 313 should_terminate = true; | 316 should_terminate = true; |
| 314 incoming_data_size = | 317 incoming_data_size = |
| 315 source_stream->length() - source_stream->bytes_written(); | 318 source_stream->length() - source_stream->bytes_written(); |
| 316 } | 319 } |
| 317 reason = WriteDataToFile( | 320 reason = WriteDataToFile( |
| 318 source_stream->offset() + source_stream->bytes_written(), | 321 source_stream->offset() + source_stream->bytes_written(), |
| 319 incoming_data.get()->data(), incoming_data_size); | 322 incoming_data.get()->data(), incoming_data_size); |
| 320 disk_writes_time_ += (base::TimeTicks::Now() - write_start); | 323 base::TimeDelta write_time = (base::TimeTicks::Now() - write_start); |
| 324 disk_writes_time_ += write_time; |
| 321 bytes_seen_ += incoming_data_size; | 325 bytes_seen_ += incoming_data_size; |
| 326 if (is_sparse_file_) { |
| 327 if (num_active_streams_ > 1) { |
| 328 disk_writes_time_with_parallel_streams_ += write_time; |
| 329 bytes_seen_with_parallel_streams_ += incoming_data_size; |
| 330 } else { |
| 331 disk_writes_time_without_parallel_streams_ += write_time; |
| 332 bytes_seen_without_parallel_streams_ += incoming_data_size; |
| 333 } |
| 334 } |
| 322 total_incoming_data_size += incoming_data_size; | 335 total_incoming_data_size += incoming_data_size; |
| 323 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) | 336 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) |
| 324 source_stream->OnWriteBytesToDisk(incoming_data_size); | 337 source_stream->OnWriteBytesToDisk(incoming_data_size); |
| 325 } | 338 } |
| 326 break; | 339 break; |
| 327 case ByteStreamReader::STREAM_COMPLETE: | 340 case ByteStreamReader::STREAM_COMPLETE: |
| 328 { | 341 { |
| 329 reason = static_cast<DownloadInterruptReason>( | 342 reason = static_cast<DownloadInterruptReason>( |
| 330 source_stream->stream_reader()->GetStatus()); | 343 source_stream->stream_reader()->GetStatus()); |
| 331 SendUpdate(); | 344 SendUpdate(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 360 // Shut down processing and signal an error to our observer. | 373 // Shut down processing and signal an error to our observer. |
| 361 // Our observer will clean us up. | 374 // Our observer will clean us up. |
| 362 source_stream->stream_reader()->RegisterCallback(base::Closure()); | 375 source_stream->stream_reader()->RegisterCallback(base::Closure()); |
| 363 weak_factory_.InvalidateWeakPtrs(); | 376 weak_factory_.InvalidateWeakPtrs(); |
| 364 SendUpdate(); // Make info up to date before error. | 377 SendUpdate(); // Make info up to date before error. |
| 365 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); | 378 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
| 366 BrowserThread::PostTask( | 379 BrowserThread::PostTask( |
| 367 BrowserThread::UI, FROM_HERE, | 380 BrowserThread::UI, FROM_HERE, |
| 368 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, | 381 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, |
| 369 reason, TotalBytesReceived(), base::Passed(&hash_state))); | 382 reason, TotalBytesReceived(), base::Passed(&hash_state))); |
| 383 num_active_streams_--; |
| 370 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { | 384 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { |
| 371 // Signal successful completion or termination of the current stream. | 385 // Signal successful completion or termination of the current stream. |
| 372 source_stream->stream_reader()->RegisterCallback(base::Closure()); | 386 source_stream->stream_reader()->RegisterCallback(base::Closure()); |
| 373 source_stream->set_finished(true); | 387 source_stream->set_finished(true); |
| 388 num_active_streams_--; |
| 374 | 389 |
| 375 // Inform observers. | 390 // Inform observers. |
| 376 SendUpdate(); | 391 SendUpdate(); |
| 377 | 392 |
| 378 // TODO(xingliu): Use slice info to determine if the file is fully | 393 // TODO(xingliu): Use slice info to determine if the file is fully |
| 379 // downloaded. | 394 // downloaded. |
| 380 bool all_stream_complete = true; | 395 bool all_stream_complete = true; |
| 381 for (auto& stream : source_streams_) { | 396 for (auto& stream : source_streams_) { |
| 382 if (!stream.second->is_finished()) { | 397 if (!stream.second->is_finished()) { |
| 383 all_stream_complete = false; | 398 all_stream_complete = false; |
| 384 break; | 399 break; |
| 385 } | 400 } |
| 386 } | 401 } |
| 387 | 402 |
| 388 // All the stream reader are completed, shut down file IO processing. | 403 // All the stream reader are completed, shut down file IO processing. |
| 389 if (all_stream_complete) { | 404 if (all_stream_complete) { |
| 390 RecordFileBandwidth(bytes_seen_, disk_writes_time_, | 405 RecordFileBandwidth(bytes_seen_, disk_writes_time_, |
| 391 base::TimeTicks::Now() - download_start_); | 406 base::TimeTicks::Now() - download_start_); |
| 407 if (is_sparse_file_) { |
| 408 RecordParallelDownloadStats(bytes_seen_with_parallel_streams_, |
| 409 disk_writes_time_with_parallel_streams_, |
| 410 bytes_seen_without_parallel_streams_, |
| 411 disk_writes_time_without_parallel_streams_); |
| 412 } |
| 392 weak_factory_.InvalidateWeakPtrs(); | 413 weak_factory_.InvalidateWeakPtrs(); |
| 393 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); | 414 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
| 394 update_timer_.reset(); | 415 update_timer_.reset(); |
| 395 BrowserThread::PostTask( | 416 BrowserThread::PostTask( |
| 396 BrowserThread::UI, FROM_HERE, | 417 BrowserThread::UI, FROM_HERE, |
| 397 base::Bind(&DownloadDestinationObserver::DestinationCompleted, | 418 base::Bind(&DownloadDestinationObserver::DestinationCompleted, |
| 398 observer_, TotalBytesReceived(), | 419 observer_, TotalBytesReceived(), |
| 399 base::Passed(&hash_state))); | 420 base::Passed(&hash_state))); |
| 400 } | 421 } |
| 401 } | 422 } |
| 402 if (net_log_.IsCapturing()) { | 423 if (net_log_.IsCapturing()) { |
| 403 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, | 424 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, |
| 404 base::Bind(&FileStreamDrainedNetLogCallback, | 425 base::Bind(&FileStreamDrainedNetLogCallback, |
| 405 total_incoming_data_size, num_buffers)); | 426 total_incoming_data_size, num_buffers)); |
| 406 } | 427 } |
| 407 } | 428 } |
| 408 | 429 |
| 409 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) { | 430 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) { |
| 410 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 431 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 411 ByteStreamReader* stream_reader = source_stream->stream_reader(); | 432 ByteStreamReader* stream_reader = source_stream->stream_reader(); |
| 412 if (stream_reader) { | 433 if (stream_reader) { |
| 413 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive, | 434 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive, |
| 414 weak_factory_.GetWeakPtr(), | 435 weak_factory_.GetWeakPtr(), |
| 415 source_stream)); | 436 source_stream)); |
| 416 StreamActive(source_stream); | 437 StreamActive(source_stream); |
| 438 num_active_streams_++; |
| 417 } | 439 } |
| 418 } | 440 } |
| 419 | 441 |
| 420 int64_t DownloadFileImpl::TotalBytesReceived() const { | 442 int64_t DownloadFileImpl::TotalBytesReceived() const { |
| 421 return file_.bytes_so_far(); | 443 return file_.bytes_so_far(); |
| 422 } | 444 } |
| 423 | 445 |
| 424 void DownloadFileImpl::SendUpdate() { | 446 void DownloadFileImpl::SendUpdate() { |
| 425 // TODO(qinmin): For each active stream, add the slice it has written so | 447 // TODO(qinmin): For each active stream, add the slice it has written so |
| 426 // far along with received_slices_. | 448 // far along with received_slices_. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 445 const base::FilePath& new_path, | 467 const base::FilePath& new_path, |
| 446 const RenameCompletionCallback& completion_callback) | 468 const RenameCompletionCallback& completion_callback) |
| 447 : option(option), | 469 : option(option), |
| 448 new_path(new_path), | 470 new_path(new_path), |
| 449 retries_left(kMaxRenameRetries), | 471 retries_left(kMaxRenameRetries), |
| 450 completion_callback(completion_callback) {} | 472 completion_callback(completion_callback) {} |
| 451 | 473 |
| 452 DownloadFileImpl::RenameParameters::~RenameParameters() {} | 474 DownloadFileImpl::RenameParameters::~RenameParameters() {} |
| 453 | 475 |
| 454 } // namespace content | 476 } // namespace content |
| OLD | NEW |