Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: content/browser/download/download_file_impl.cc

Issue 2738063002: Verify that all slice are downloaded when a stream complete (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/download/download_file_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "content/browser/byte_stream.h" 16 #include "content/browser/byte_stream.h"
17 #include "content/browser/download/download_create_info.h" 17 #include "content/browser/download/download_create_info.h"
18 #include "content/browser/download/download_destination_observer.h" 18 #include "content/browser/download/download_destination_observer.h"
19 #include "content/browser/download/download_interrupt_reasons_impl.h" 19 #include "content/browser/download/download_interrupt_reasons_impl.h"
20 #include "content/browser/download/download_net_log_parameters.h" 20 #include "content/browser/download/download_net_log_parameters.h"
21 #include "content/browser/download/download_stats.h" 21 #include "content/browser/download/download_stats.h"
22 #include "content/browser/download/parallel_download_utils.h"
22 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
23 #include "crypto/secure_hash.h" 24 #include "crypto/secure_hash.h"
24 #include "crypto/sha2.h" 25 #include "crypto/sha2.h"
25 #include "net/base/io_buffer.h" 26 #include "net/base/io_buffer.h"
26 #include "net/log/net_log.h" 27 #include "net/log/net_log.h"
27 #include "net/log/net_log_event_type.h" 28 #include "net/log/net_log_event_type.h"
28 #include "net/log/net_log_source.h" 29 #include "net/log/net_log_source.h"
29 #include "net/log/net_log_source_type.h" 30 #include "net/log/net_log_source_type.h"
30 31
31 namespace content { 32 namespace content {
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 base::Bind(&DownloadDestinationObserver::DestinationError, observer_, 361 base::Bind(&DownloadDestinationObserver::DestinationError, observer_,
361 reason, TotalBytesReceived(), base::Passed(&hash_state))); 362 reason, TotalBytesReceived(), base::Passed(&hash_state)));
362 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) { 363 } else if (state == ByteStreamReader::STREAM_COMPLETE || should_terminate) {
363 // Signal successful completion or termination of the current stream. 364 // Signal successful completion or termination of the current stream.
364 source_stream->stream_reader()->RegisterCallback(base::Closure()); 365 source_stream->stream_reader()->RegisterCallback(base::Closure());
365 source_stream->set_finished(true); 366 source_stream->set_finished(true);
366 367
367 // Inform observers. 368 // Inform observers.
368 SendUpdate(); 369 SendUpdate();
369 370
370 // TODO(xingliu): Use slice info to determine if the file is fully
371 // downloaded.
372 bool all_stream_complete = true;
373 for (auto& stream : source_streams_) {
374 if (!stream.second->is_finished()) {
375 all_stream_complete = false;
376 break;
377 }
378 }
379
380 // All the stream reader are completed, shut down file IO processing. 371 // All the stream reader are completed, shut down file IO processing.
381 if (all_stream_complete) { 372 if (IsDownloadCompleted()) {
382 RecordFileBandwidth(bytes_seen_, disk_writes_time_, 373 RecordFileBandwidth(bytes_seen_, disk_writes_time_,
383 base::TimeTicks::Now() - download_start_); 374 base::TimeTicks::Now() - download_start_);
384 weak_factory_.InvalidateWeakPtrs(); 375 weak_factory_.InvalidateWeakPtrs();
385 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); 376 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish();
386 update_timer_.reset(); 377 update_timer_.reset();
387 BrowserThread::PostTask( 378 BrowserThread::PostTask(
388 BrowserThread::UI, FROM_HERE, 379 BrowserThread::UI, FROM_HERE,
389 base::Bind(&DownloadDestinationObserver::DestinationCompleted, 380 base::Bind(&DownloadDestinationObserver::DestinationCompleted,
390 observer_, TotalBytesReceived(), 381 observer_, TotalBytesReceived(),
391 base::Passed(&hash_state))); 382 base::Passed(&hash_state)));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 417
427 void DownloadFileImpl::WillWriteToDisk(size_t data_len) { 418 void DownloadFileImpl::WillWriteToDisk(size_t data_len) {
428 if (!update_timer_->IsRunning()) { 419 if (!update_timer_->IsRunning()) {
429 update_timer_->Start(FROM_HERE, 420 update_timer_->Start(FROM_HERE,
430 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 421 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
431 this, &DownloadFileImpl::SendUpdate); 422 this, &DownloadFileImpl::SendUpdate);
432 } 423 }
433 rate_estimator_.Increment(data_len); 424 rate_estimator_.Increment(data_len);
434 } 425 }
435 426
427 bool DownloadFileImpl::IsDownloadCompleted() {
428 SourceStream* stream_for_last_slice = nullptr;
429 int64_t last_slice_offset = 0;
David Trainor- moved to gerrit 2017/03/09 17:23:10 You need to set this inside the if block below rig
qinmin 2017/03/09 17:42:25 Good catch. I was using steam_for_last_slice = sou
430 for (auto& stream : source_streams_) {
431 SourceStream* source_stream = stream.second.get();
432 if (source_stream->offset() >= last_slice_offset &&
433 source_stream->bytes_written() > 0) {
434 stream_for_last_slice = source_stream;
435 }
436 if (!source_stream->is_finished())
437 return false;
438 }
439
440 if (!is_sparse_file_)
441 return true;
442
443 // Verify that all the file slices have been downloaded.
444 std::vector<DownloadItem::ReceivedSlice> slices_to_download =
445 FindSlicesToDownload(received_slices_);
446 if (slices_to_download.size() > 1) {
447 // If there are 1 or more holes in the file, download is not finished.
448 // Some streams might not have been added to |source_streams_| yet.
449 return false;
450 } else if (stream_for_last_slice) {
451 DCHECK_EQ(slices_to_download[0].received_bytes,
452 DownloadSaveInfo::kLengthFullContent);
453 // The last stream should not have a length limit. If it has, it might
454 // not reach the end of the file.
455 if (stream_for_last_slice->length() !=
456 DownloadSaveInfo::kLengthFullContent) {
457 return false;
458 }
459 DCHECK_EQ(slices_to_download[0].offset,
460 stream_for_last_slice->offset() +
461 stream_for_last_slice->bytes_written());
462 }
463
464 return true;
465 }
466
436 DownloadFileImpl::RenameParameters::RenameParameters( 467 DownloadFileImpl::RenameParameters::RenameParameters(
437 RenameOption option, 468 RenameOption option,
438 const base::FilePath& new_path, 469 const base::FilePath& new_path,
439 const RenameCompletionCallback& completion_callback) 470 const RenameCompletionCallback& completion_callback)
440 : option(option), 471 : option(option),
441 new_path(new_path), 472 new_path(new_path),
442 retries_left(kMaxRenameRetries), 473 retries_left(kMaxRenameRetries),
443 completion_callback(completion_callback) {} 474 completion_callback(completion_callback) {}
444 475
445 DownloadFileImpl::RenameParameters::~RenameParameters() {} 476 DownloadFileImpl::RenameParameters::~RenameParameters() {}
446 477
447 } // namespace content 478 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/download_file_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698