Chromium Code Reviews| 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 record_stream_bandwidth_(true), | |
| 76 bytes_seen_with_parallel_streams_(0), | |
| 77 bytes_seen_without_parallel_streams_(0), | |
| 74 received_slices_(received_slices), | 78 received_slices_(received_slices), |
| 75 observer_(observer), | 79 observer_(observer), |
| 76 weak_factory_(this) { | 80 weak_factory_(this) { |
| 77 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>( | 81 source_streams_[save_info_->offset] = base::MakeUnique<SourceStream>( |
| 78 save_info_->offset, DownloadSaveInfo::kLengthFullContent); | 82 save_info_->offset, DownloadSaveInfo::kLengthFullContent); |
| 79 DCHECK(source_streams_.size() == static_cast<size_t>(1)); | 83 DCHECK(source_streams_.size() == static_cast<size_t>(1)); |
| 80 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader)); | 84 source_streams_[save_info_->offset]->SetByteStream(std::move(stream_reader)); |
| 81 | 85 |
| 82 download_item_net_log.AddEvent( | 86 download_item_net_log.AddEvent( |
| 83 net::NetLogEventType::DOWNLOAD_FILE_CREATED, | 87 net::NetLogEventType::DOWNLOAD_FILE_CREATED, |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 109 std::move(save_info_->file), bytes_so_far, | 113 std::move(save_info_->file), bytes_so_far, |
| 110 save_info_->hash_of_partial_file, | 114 save_info_->hash_of_partial_file, |
| 111 std::move(save_info_->hash_state), is_sparse_file_); | 115 std::move(save_info_->hash_state), is_sparse_file_); |
| 112 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { | 116 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 113 BrowserThread::PostTask( | 117 BrowserThread::PostTask( |
| 114 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); | 118 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); |
| 115 return; | 119 return; |
| 116 } | 120 } |
| 117 | 121 |
| 118 download_start_ = base::TimeTicks::Now(); | 122 download_start_ = base::TimeTicks::Now(); |
| 123 last_update_time_ = download_start_; | |
| 119 | 124 |
| 120 // Primarily to make reset to zero in restart visible to owner. | 125 // Primarily to make reset to zero in restart visible to owner. |
| 121 SendUpdate(); | 126 SendUpdate(); |
| 122 | 127 |
| 123 // Initial pull from the straw. | 128 // Initial pull from the straw. |
| 124 for (auto& source_stream : source_streams_) | 129 for (auto& source_stream : source_streams_) |
| 125 RegisterAndActivateStream(source_stream.second.get()); | 130 RegisterAndActivateStream(source_stream.second.get()); |
| 126 | 131 |
| 127 BrowserThread::PostTask( | 132 BrowserThread::PostTask( |
| 128 BrowserThread::UI, FROM_HERE, base::Bind( | 133 BrowserThread::UI, FROM_HERE, base::Bind( |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 } | 277 } |
| 273 | 278 |
| 274 const base::FilePath& DownloadFileImpl::FullPath() const { | 279 const base::FilePath& DownloadFileImpl::FullPath() const { |
| 275 return file_.full_path(); | 280 return file_.full_path(); |
| 276 } | 281 } |
| 277 | 282 |
| 278 bool DownloadFileImpl::InProgress() const { | 283 bool DownloadFileImpl::InProgress() const { |
| 279 return file_.in_progress(); | 284 return file_.in_progress(); |
| 280 } | 285 } |
| 281 | 286 |
| 287 void DownloadFileImpl::Pause() { | |
| 288 record_stream_bandwidth_ = false; | |
|
xingliu
2017/03/17 00:02:15
I think we didn't set it to true again, and didn't
David Trainor- moved to gerrit
2017/03/17 07:25:40
Do we need to reset last_update_time_ on resume as
qinmin
2017/03/17 19:52:54
We don't record UMA even if resume is called, the
qinmin
2017/03/17 19:52:55
we should stop recording if a download is ever pau
| |
| 289 } | |
| 290 | |
| 282 void DownloadFileImpl::StreamActive(SourceStream* source_stream) { | 291 void DownloadFileImpl::StreamActive(SourceStream* source_stream) { |
| 283 DCHECK(source_stream->stream_reader()); | 292 DCHECK(source_stream->stream_reader()); |
| 284 base::TimeTicks start(base::TimeTicks::Now()); | 293 base::TimeTicks start(base::TimeTicks::Now()); |
| 285 base::TimeTicks now; | 294 base::TimeTicks now; |
| 286 scoped_refptr<net::IOBuffer> incoming_data; | 295 scoped_refptr<net::IOBuffer> incoming_data; |
| 287 size_t incoming_data_size = 0; | 296 size_t incoming_data_size = 0; |
| 288 size_t total_incoming_data_size = 0; | 297 size_t total_incoming_data_size = 0; |
| 289 size_t num_buffers = 0; | 298 size_t num_buffers = 0; |
| 290 bool should_terminate = false; | 299 bool should_terminate = false; |
| 291 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); | 300 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 // Shut down processing and signal an error to our observer. | 369 // Shut down processing and signal an error to our observer. |
| 361 // Our observer will clean us up. | 370 // Our observer will clean us up. |
| 362 source_stream->stream_reader()->RegisterCallback(base::Closure()); | 371 source_stream->stream_reader()->RegisterCallback(base::Closure()); |
| 363 weak_factory_.InvalidateWeakPtrs(); | 372 weak_factory_.InvalidateWeakPtrs(); |
| 364 SendUpdate(); // Make info up to date before error. | 373 SendUpdate(); // Make info up to date before error. |
| 365 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); | 374 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
| 366 BrowserThread::PostTask( | 375 BrowserThread::PostTask( |
| 367 BrowserThread::UI, FROM_HERE, | 376 BrowserThread::UI, FROM_HERE, |
| 368 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, | 377 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, |
| 369 reason, TotalBytesReceived(), base::Passed(&hash_state))); | 378 reason, TotalBytesReceived(), base::Passed(&hash_state))); |
| 379 num_active_streams_--; | |
| 370 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { | 380 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { |
| 371 // Signal successful completion or termination of the current stream. | 381 // Signal successful completion or termination of the current stream. |
| 372 source_stream->stream_reader()->RegisterCallback(base::Closure()); | 382 source_stream->stream_reader()->RegisterCallback(base::Closure()); |
| 373 source_stream->set_finished(true); | 383 source_stream->set_finished(true); |
| 384 num_active_streams_--; | |
| 374 | 385 |
| 375 // Inform observers. | 386 // Inform observers. |
| 376 SendUpdate(); | 387 SendUpdate(); |
| 377 | 388 |
| 378 // TODO(xingliu): Use slice info to determine if the file is fully | 389 // TODO(xingliu): Use slice info to determine if the file is fully |
| 379 // downloaded. | 390 // downloaded. |
| 380 bool all_stream_complete = true; | 391 bool all_stream_complete = true; |
| 381 for (auto& stream : source_streams_) { | 392 for (auto& stream : source_streams_) { |
| 382 if (!stream.second->is_finished()) { | 393 if (!stream.second->is_finished()) { |
| 383 all_stream_complete = false; | 394 all_stream_complete = false; |
| 384 break; | 395 break; |
| 385 } | 396 } |
| 386 } | 397 } |
| 387 | 398 |
| 388 // All the stream reader are completed, shut down file IO processing. | 399 // All the stream reader are completed, shut down file IO processing. |
| 389 if (all_stream_complete) { | 400 if (all_stream_complete) { |
| 390 RecordFileBandwidth(bytes_seen_, disk_writes_time_, | 401 RecordFileBandwidth(bytes_seen_, disk_writes_time_, |
| 391 base::TimeTicks::Now() - download_start_); | 402 base::TimeTicks::Now() - download_start_); |
| 403 if (is_sparse_file_) { | |
| 404 RecordParallelDownloadStats(bytes_seen_with_parallel_streams_, | |
| 405 download_time_with_parallel_streams_, | |
| 406 bytes_seen_without_parallel_streams_, | |
| 407 download_time_without_parallel_streams_); | |
| 408 } | |
| 392 weak_factory_.InvalidateWeakPtrs(); | 409 weak_factory_.InvalidateWeakPtrs(); |
| 393 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); | 410 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
| 394 update_timer_.reset(); | 411 update_timer_.reset(); |
| 395 BrowserThread::PostTask( | 412 BrowserThread::PostTask( |
| 396 BrowserThread::UI, FROM_HERE, | 413 BrowserThread::UI, FROM_HERE, |
| 397 base::Bind(&DownloadDestinationObserver::DestinationCompleted, | 414 base::Bind(&DownloadDestinationObserver::DestinationCompleted, |
| 398 observer_, TotalBytesReceived(), | 415 observer_, TotalBytesReceived(), |
| 399 base::Passed(&hash_state))); | 416 base::Passed(&hash_state))); |
| 400 } | 417 } |
| 401 } | 418 } |
| 402 if (net_log_.IsCapturing()) { | 419 if (net_log_.IsCapturing()) { |
| 403 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, | 420 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, |
| 404 base::Bind(&FileStreamDrainedNetLogCallback, | 421 base::Bind(&FileStreamDrainedNetLogCallback, |
| 405 total_incoming_data_size, num_buffers)); | 422 total_incoming_data_size, num_buffers)); |
| 406 } | 423 } |
| 407 } | 424 } |
| 408 | 425 |
| 409 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) { | 426 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) { |
| 410 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 427 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 411 ByteStreamReader* stream_reader = source_stream->stream_reader(); | 428 ByteStreamReader* stream_reader = source_stream->stream_reader(); |
| 412 if (stream_reader) { | 429 if (stream_reader) { |
| 413 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive, | 430 stream_reader->RegisterCallback(base::Bind(&DownloadFileImpl::StreamActive, |
| 414 weak_factory_.GetWeakPtr(), | 431 weak_factory_.GetWeakPtr(), |
| 415 source_stream)); | 432 source_stream)); |
| 416 StreamActive(source_stream); | 433 StreamActive(source_stream); |
| 434 num_active_streams_++; | |
| 417 } | 435 } |
| 418 } | 436 } |
| 419 | 437 |
| 420 int64_t DownloadFileImpl::TotalBytesReceived() const { | 438 int64_t DownloadFileImpl::TotalBytesReceived() const { |
| 421 return file_.bytes_so_far(); | 439 return file_.bytes_so_far(); |
| 422 } | 440 } |
| 423 | 441 |
| 424 void DownloadFileImpl::SendUpdate() { | 442 void DownloadFileImpl::SendUpdate() { |
| 425 // TODO(qinmin): For each active stream, add the slice it has written so | 443 // TODO(qinmin): For each active stream, add the slice it has written so |
| 426 // far along with received_slices_. | 444 // far along with received_slices_. |
| 427 BrowserThread::PostTask( | 445 BrowserThread::PostTask( |
| 428 BrowserThread::UI, FROM_HERE, | 446 BrowserThread::UI, FROM_HERE, |
| 429 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_, | 447 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_, |
| 430 TotalBytesReceived(), rate_estimator_.GetCountPerSecond(), | 448 TotalBytesReceived(), rate_estimator_.GetCountPerSecond(), |
| 431 received_slices_)); | 449 received_slices_)); |
| 432 } | 450 } |
| 433 | 451 |
| 434 void DownloadFileImpl::WillWriteToDisk(size_t data_len) { | 452 void DownloadFileImpl::WillWriteToDisk(size_t data_len) { |
| 435 if (!update_timer_->IsRunning()) { | 453 if (!update_timer_->IsRunning()) { |
| 436 update_timer_->Start(FROM_HERE, | 454 update_timer_->Start(FROM_HERE, |
| 437 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), | 455 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), |
| 438 this, &DownloadFileImpl::SendUpdate); | 456 this, &DownloadFileImpl::SendUpdate); |
| 439 } | 457 } |
| 440 rate_estimator_.Increment(data_len); | 458 rate_estimator_.Increment(data_len); |
| 459 if (is_sparse_file_) { | |
| 460 base::TimeTicks now = base::TimeTicks::Now(); | |
| 461 base::TimeDelta time_elapsed = (now - last_update_time_); | |
| 462 last_update_time_ = now; | |
| 463 if (num_active_streams_ > 1) { | |
| 464 download_time_with_parallel_streams_ += time_elapsed; | |
| 465 bytes_seen_with_parallel_streams_ += data_len; | |
| 466 } else { | |
| 467 download_time_without_parallel_streams_ += time_elapsed; | |
| 468 bytes_seen_without_parallel_streams_ += data_len; | |
| 469 } | |
| 470 } | |
| 441 } | 471 } |
| 442 | 472 |
| 443 DownloadFileImpl::RenameParameters::RenameParameters( | 473 DownloadFileImpl::RenameParameters::RenameParameters( |
| 444 RenameOption option, | 474 RenameOption option, |
| 445 const base::FilePath& new_path, | 475 const base::FilePath& new_path, |
| 446 const RenameCompletionCallback& completion_callback) | 476 const RenameCompletionCallback& completion_callback) |
| 447 : option(option), | 477 : option(option), |
| 448 new_path(new_path), | 478 new_path(new_path), |
| 449 retries_left(kMaxRenameRetries), | 479 retries_left(kMaxRenameRetries), |
| 450 completion_callback(completion_callback) {} | 480 completion_callback(completion_callback) {} |
| 451 | 481 |
| 452 DownloadFileImpl::RenameParameters::~RenameParameters() {} | 482 DownloadFileImpl::RenameParameters::~RenameParameters() {} |
| 453 | 483 |
| 454 } // namespace content | 484 } // namespace content |
| OLD | NEW |