| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 bool is_sparse_file, | 69 bool is_sparse_file, |
| 70 base::WeakPtr<DownloadDestinationObserver> observer) | 70 base::WeakPtr<DownloadDestinationObserver> observer) |
| 71 : net_log_( | 71 : net_log_( |
| 72 net::NetLogWithSource::Make(download_item_net_log.net_log(), | 72 net::NetLogWithSource::Make(download_item_net_log.net_log(), |
| 73 net::NetLogSourceType::DOWNLOAD_FILE)), | 73 net::NetLogSourceType::DOWNLOAD_FILE)), |
| 74 file_(net_log_), | 74 file_(net_log_), |
| 75 save_info_(std::move(save_info)), | 75 save_info_(std::move(save_info)), |
| 76 default_download_directory_(default_download_directory), | 76 default_download_directory_(default_download_directory), |
| 77 is_sparse_file_(is_sparse_file), | 77 is_sparse_file_(is_sparse_file), |
| 78 bytes_seen_(0), | 78 bytes_seen_(0), |
| 79 num_active_streams_(0), |
| 80 record_stream_bandwidth_(true), |
| 81 bytes_seen_with_parallel_streams_(0), |
| 82 bytes_seen_without_parallel_streams_(0), |
| 79 received_slices_(received_slices), | 83 received_slices_(received_slices), |
| 80 observer_(observer), | 84 observer_(observer), |
| 81 weak_factory_(this) { | 85 weak_factory_(this) { |
| 82 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>( | 86 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>( |
| 83 save_info_->offset, DownloadSaveInfo::kLengthFullContent); | 87 save_info_->offset, DownloadSaveInfo::kLengthFullContent); |
| 84 DCHECK(source_streams_.size() == static_cast<size_t>(1)); | 88 DCHECK(source_streams_.size() == static_cast<size_t>(1)); |
| 85 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader)); | 89 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader)); |
| 86 | 90 |
| 87 download_item_net_log.AddEvent( | 91 download_item_net_log.AddEvent( |
| 88 net::NetLogEventType::DOWNLOAD_FILE_CREATED, | 92 net::NetLogEventType::DOWNLOAD_FILE_CREATED, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 114 std::move(save_info_->file), bytes_so_far, | 118 std::move(save_info_->file), bytes_so_far, |
| 115 save_info_->hash_of_partial_file, | 119 save_info_->hash_of_partial_file, |
| 116 std::move(save_info_->hash_state), is_sparse_file_); | 120 std::move(save_info_->hash_state), is_sparse_file_); |
| 117 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 121 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 118 BrowserThread::PostTask( | 122 BrowserThread::PostTask( |
| 119 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); | 123 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); |
| 120 return; | 124 return; |
| 121 } | 125 } |
| 122 | 126 |
| 123 download_start_ = base::TimeTicks::Now(); | 127 download_start_ = base::TimeTicks::Now(); |
| 128 last_update_time_ = download_start_; |
| 124 | 129 |
| 125 // Primarily to make reset to zero in restart visible to owner. | 130 // Primarily to make reset to zero in restart visible to owner. |
| 126 SendUpdate(); | 131 SendUpdate(); |
| 127 | 132 |
| 128 // Initial pull from the straw. | 133 // Initial pull from the straw. |
| 129 for (auto& source_stream : source_streams_) | 134 for (auto& source_stream : source_streams_) |
| 130 RegisterAndActivateStream(source_stream.second.get()); | 135 RegisterAndActivateStream(source_stream.second.get()); |
| 131 | 136 |
| 132 BrowserThread::PostTask( | 137 BrowserThread::PostTask( |
| 133 BrowserThread::UI, FROM_HERE, base::Bind( | 138 BrowserThread::UI, FROM_HERE, base::Bind( |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 } | 282 } |
| 278 | 283 |
| 279 const base::FilePath& DownloadFileImpl::FullPath() const { | 284 const base::FilePath& DownloadFileImpl::FullPath() const { |
| 280 return file_.full_path(); | 285 return file_.full_path(); |
| 281 } | 286 } |
| 282 | 287 |
| 283 bool DownloadFileImpl::InProgress() const { | 288 bool DownloadFileImpl::InProgress() const { |
| 284 return file_.in_progress(); | 289 return file_.in_progress(); |
| 285 } | 290 } |
| 286 | 291 |
| 292 void DownloadFileImpl::WasPaused() { |
| 293 record_stream_bandwidth_ = false; |
| 294 } |
| 295 |
| 287 void DownloadFileImpl::StreamActive(SourceStream* source_stream) { | 296 void DownloadFileImpl::StreamActive(SourceStream* source_stream) { |
| 288 DCHECK(source_stream->stream_reader()); | 297 DCHECK(source_stream->stream_reader()); |
| 289 base::TimeTicks start(base::TimeTicks::Now()); | 298 base::TimeTicks start(base::TimeTicks::Now()); |
| 290 base::TimeTicks now; | 299 base::TimeTicks now; |
| 291 scoped_refptr<net::IOBuffer> incoming_data; | 300 scoped_refptr<net::IOBuffer> incoming_data; |
| 292 size_t incoming_data_size = 0; | 301 size_t incoming_data_size = 0; |
| 293 size_t total_incoming_data_size = 0; | 302 size_t total_incoming_data_size = 0; |
| 294 size_t num_buffers = 0; | 303 size_t num_buffers = 0; |
| 295 bool should_terminate = false; | 304 bool should_terminate = false; |
| 296 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); | 305 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 // Shut down processing and signal an error to our observer. | 387 // Shut down processing and signal an error to our observer. |
| 379 // Our observer will clean us up. | 388 // Our observer will clean us up. |
| 380 source_stream->stream_reader()->RegisterCallback(base::Closure()); | 389 source_stream->stream_reader()->RegisterCallback(base::Closure()); |
| 381 weak_factory_.InvalidateWeakPtrs(); | 390 weak_factory_.InvalidateWeakPtrs(); |
| 382 SendUpdate(); // Make info up to date before error. | 391 SendUpdate(); // Make info up to date before error. |
| 383 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); | 392 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
| 384 BrowserThread::PostTask( | 393 BrowserThread::PostTask( |
| 385 BrowserThread::UI, FROM_HERE, | 394 BrowserThread::UI, FROM_HERE, |
| 386 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, | 395 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, |
| 387 reason, TotalBytesReceived(), base::Passed(&hash_state))); | 396 reason, TotalBytesReceived(), base::Passed(&hash_state))); |
| 397 num_active_streams_--; |
| 388 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { | 398 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { |
| 389 // Signal successful completion or termination of the current stream. | 399 // Signal successful completion or termination of the current stream. |
| 390 source_stream->stream_reader()->RegisterCallback(base::Closure()); | 400 source_stream->stream_reader()->RegisterCallback(base::Closure()); |
| 391 source_stream->set_finished(true); | 401 source_stream->set_finished(true); |
| 402 num_active_streams_--; |
| 392 | 403 |
| 393 // Inform observers. | 404 // Inform observers. |
| 394 SendUpdate(); | 405 SendUpdate(); |
| 395 | 406 |
| 396 // All the stream reader are completed, shut down file IO processing. | 407 // All the stream reader are completed, shut down file IO processing. |
| 397 if (IsDownloadCompleted()) { | 408 if (IsDownloadCompleted()) { |
| 398 RecordFileBandwidth(bytes_seen_, disk_writes_time_, | 409 RecordFileBandwidth(bytes_seen_, disk_writes_time_, |
| 399 base::TimeTicks::Now() - download_start_); | 410 base::TimeTicks::Now() - download_start_); |
| 411 if (is_sparse_file_ && record_stream_bandwidth_) { |
| 412 RecordParallelDownloadStats(bytes_seen_with_parallel_streams_, |
| 413 download_time_with_parallel_streams_, |
| 414 bytes_seen_without_parallel_streams_, |
| 415 download_time_without_parallel_streams_); |
| 416 } |
| 400 weak_factory_.InvalidateWeakPtrs(); | 417 weak_factory_.InvalidateWeakPtrs(); |
| 401 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); | 418 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
| 402 update_timer_.reset(); | 419 update_timer_.reset(); |
| 403 BrowserThread::PostTask( | 420 BrowserThread::PostTask( |
| 404 BrowserThread::UI, FROM_HERE, | 421 BrowserThread::UI, FROM_HERE, |
| 405 base::Bind(&DownloadDestinationObserver::DestinationCompleted, | 422 base::Bind(&DownloadDestinationObserver::DestinationCompleted, |
| 406 observer_, TotalBytesReceived(), | 423 observer_, TotalBytesReceived(), |
| 407 base::Passed(&hash_state))); | 424 base::Passed(&hash_state))); |
| 408 } | 425 } |
| 409 } | 426 } |
| 410 if (net_log_.IsCapturing()) { | 427 if (net_log_.IsCapturing()) { |
| 411 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, | 428 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, |
| 412 base::Bind(&FileStreamDrainedNetLogCallback, | 429 base::Bind(&FileStreamDrainedNetLogCallback, |
| 413 total_incoming_data_size, num_buffers)); | 430 total_incoming_data_size, num_buffers)); |
| 414 } | 431 } |
| 415 } | 432 } |
| 416 | 433 |
| 417 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) { | 434 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) { |
| 418 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 435 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 419 ByteStreamReader* stream_reader = source_stream->stream_reader(); | 436 ByteStreamReader* stream_reader = source_stream->stream_reader(); |
| 420 if (stream_reader) { | 437 if (stream_reader) { |
| 421 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive, | 438 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive, |
| 422 weak_factory_.GetWeakPtr(), | 439 weak_factory_.GetWeakPtr(), |
| 423 source_stream)); | 440 source_stream)); |
| 424 StreamActive(source_stream); | 441 StreamActive(source_stream); |
| 442 num_active_streams_++; |
| 425 } | 443 } |
| 426 } | 444 } |
| 427 | 445 |
| 428 int64_t DownloadFileImpl::TotalBytesReceived() const { | 446 int64_t DownloadFileImpl::TotalBytesReceived() const { |
| 429 return file_.bytes_so_far(); | 447 return file_.bytes_so_far(); |
| 430 } | 448 } |
| 431 | 449 |
| 432 void DownloadFileImpl::SendUpdate() { | 450 void DownloadFileImpl::SendUpdate() { |
| 433 // TODO(qinmin): For each active stream, add the slice it has written so | 451 // TODO(qinmin): For each active stream, add the slice it has written so |
| 434 // far along with received_slices_. | 452 // far along with received_slices_. |
| 435 BrowserThread::PostTask( | 453 BrowserThread::PostTask( |
| 436 BrowserThread::UI, FROM_HERE, | 454 BrowserThread::UI, FROM_HERE, |
| 437 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_, | 455 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_, |
| 438 TotalBytesReceived(), rate_estimator_.GetCountPerSecond(), | 456 TotalBytesReceived(), rate_estimator_.GetCountPerSecond(), |
| 439 received_slices_)); | 457 received_slices_)); |
| 440 } | 458 } |
| 441 | 459 |
| 442 void DownloadFileImpl::WillWriteToDisk(size_t data_len) { | 460 void DownloadFileImpl::WillWriteToDisk(size_t data_len) { |
| 443 if (!update_timer_->IsRunning()) { | 461 if (!update_timer_->IsRunning()) { |
| 444 update_timer_->Start(FROM_HERE, | 462 update_timer_->Start(FROM_HERE, |
| 445 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), | 463 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), |
| 446 this, &DownloadFileImpl::SendUpdate); | 464 this, &DownloadFileImpl::SendUpdate); |
| 447 } | 465 } |
| 448 rate_estimator_.Increment(data_len); | 466 rate_estimator_.Increment(data_len); |
| 467 if (is_sparse_file_) { |
| 468 base::TimeTicks now = base::TimeTicks::Now(); |
| 469 base::TimeDelta time_elapsed = (now - last_update_time_); |
| 470 last_update_time_ = now; |
| 471 if (num_active_streams_ > 1) { |
| 472 download_time_with_parallel_streams_ += time_elapsed; |
| 473 bytes_seen_with_parallel_streams_ += data_len; |
| 474 } else { |
| 475 download_time_without_parallel_streams_ += time_elapsed; |
| 476 bytes_seen_without_parallel_streams_ += data_len; |
| 477 } |
| 478 } |
| 449 } | 479 } |
| 450 | 480 |
| 451 void DownloadFileImpl::AddNewSlice(int64_t offset, int64_t length) { | 481 void DownloadFileImpl::AddNewSlice(int64_t offset, int64_t length) { |
| 452 if (!is_sparse_file_) | 482 if (!is_sparse_file_) |
| 453 return; | 483 return; |
| 454 size_t index = AddOrMergeReceivedSliceIntoSortedArray( | 484 size_t index = AddOrMergeReceivedSliceIntoSortedArray( |
| 455 DownloadItem::ReceivedSlice(offset, length), received_slices_); | 485 DownloadItem::ReceivedSlice(offset, length), received_slices_); |
| 456 // Check if the slice is added as a new slice, or merged with an existing one. | 486 // Check if the slice is added as a new slice, or merged with an existing one. |
| 457 bool slice_added = (offset == received_slices_[index].offset); | 487 bool slice_added = (offset == received_slices_[index].offset); |
| 458 // Update the index of exising SourceStreams. | 488 // Update the index of exising SourceStreams. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 const base::FilePath& new_path, | 550 const base::FilePath& new_path, |
| 521 const RenameCompletionCallback& completion_callback) | 551 const RenameCompletionCallback& completion_callback) |
| 522 : option(option), | 552 : option(option), |
| 523 new_path(new_path), | 553 new_path(new_path), |
| 524 retries_left(kMaxRenameRetries), | 554 retries_left(kMaxRenameRetries), |
| 525 completion_callback(completion_callback) {} | 555 completion_callback(completion_callback) {} |
| 526 | 556 |
| 527 DownloadFileImpl::RenameParameters::~RenameParameters() {} | 557 DownloadFileImpl::RenameParameters::~RenameParameters() {} |
| 528 | 558 |
| 529 } // namespace content | 559 } // namespace content |
| OLD | NEW |