Index: content/browser/download/download_file_impl.cc |
diff --git a/content/browser/download/download_file_impl.cc b/content/browser/download/download_file_impl.cc |
index b8d876155d3821f47e1aba267005659ffb683779..6378b9c8d3b74e5b74e2a5292902aeead491c6eb 100644 |
--- a/content/browser/download/download_file_impl.cc |
+++ b/content/browser/download/download_file_impl.cc |
@@ -14,11 +14,13 @@ |
#include "base/values.h" |
#include "content/browser/byte_stream.h" |
#include "content/browser/download/download_create_info.h" |
+#include "content/browser/download/download_destination_observer.h" |
#include "content/browser/download/download_interrupt_reasons_impl.h" |
#include "content/browser/download/download_net_log_parameters.h" |
#include "content/browser/download/download_stats.h" |
#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/download_destination_observer.h" |
+#include "crypto/secure_hash.h" |
+#include "crypto/sha2.h" |
#include "net/base/io_buffer.h" |
namespace content { |
@@ -29,29 +31,19 @@ const int kMaxTimeBlockingFileThreadMs = 1000; |
// These constants control the default retry behavior for failing renames. Each |
// retry is performed after a delay that is twice the previous delay. The |
// initial delay is specified by kInitialRenameRetryDelayMs. |
-const int kMaxRenameRetries = 3; |
const int kInitialRenameRetryDelayMs = 200; |
-int DownloadFile::number_active_objects_ = 0; |
+// Number of times a failing rename is retried before giving up. |
+const int kMaxRenameRetries = 3; |
DownloadFileImpl::DownloadFileImpl( |
- const DownloadSaveInfo& save_info, |
+ scoped_ptr<DownloadSaveInfo> save_info, |
const base::FilePath& default_download_directory, |
- const GURL& url, |
- const GURL& referrer_url, |
- bool calculate_hash, |
- base::File file, |
scoped_ptr<ByteStreamReader> stream, |
const net::BoundNetLog& bound_net_log, |
base::WeakPtr<DownloadDestinationObserver> observer) |
- : file_(save_info.file_path, |
- url, |
- referrer_url, |
- save_info.offset, |
- calculate_hash, |
- save_info.hash_state, |
- std::move(file), |
- bound_net_log), |
+ : file_(bound_net_log), |
+ save_info_(std::move(save_info)), |
default_download_directory_(default_download_directory), |
stream_reader_(std::move(stream)), |
bytes_seen_(0), |
@@ -61,7 +53,6 @@ DownloadFileImpl::DownloadFileImpl( |
DownloadFileImpl::~DownloadFileImpl() { |
DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
- --number_active_objects_; |
} |
void DownloadFileImpl::Initialize(const InitializeCallback& callback) { |
@@ -69,7 +60,12 @@ void DownloadFileImpl::Initialize(const InitializeCallback& callback) { |
update_timer_.reset(new base::RepeatingTimer()); |
DownloadInterruptReason result = |
- file_.Initialize(default_download_directory_); |
+ file_.Initialize(save_info_->file_path, |
+ default_download_directory_, |
+ std::move(save_info_->file), |
+ save_info_->offset, |
+ save_info_->hash_of_partial_file, |
+ std::move(save_info_->hash_state)); |
if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { |
BrowserThread::PostTask( |
BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); |
@@ -90,8 +86,6 @@ void DownloadFileImpl::Initialize(const InitializeCallback& callback) { |
BrowserThread::PostTask( |
BrowserThread::UI, FROM_HERE, base::Bind( |
callback, DOWNLOAD_INTERRUPT_REASON_NONE)); |
- |
- ++number_active_objects_; |
} |
DownloadInterruptReason DownloadFileImpl::AppendDataToFile( |
@@ -110,18 +104,23 @@ DownloadInterruptReason DownloadFileImpl::AppendDataToFile( |
void DownloadFileImpl::RenameAndUniquify( |
const base::FilePath& full_path, |
const RenameCompletionCallback& callback) { |
- RenameWithRetryInternal( |
- full_path, UNIQUIFY, kMaxRenameRetries, base::TimeTicks(), callback); |
+ scoped_ptr<RenameParameters> parameters( |
+ new RenameParameters(UNIQUIFY, full_path, callback)); |
+ RenameWithRetryInternal(std::move(parameters)); |
} |
void DownloadFileImpl::RenameAndAnnotate( |
const base::FilePath& full_path, |
+ const std::string& client_guid, |
+ const GURL& source_url, |
+ const GURL& referrer_url, |
const RenameCompletionCallback& callback) { |
- RenameWithRetryInternal(full_path, |
- ANNOTATE_WITH_SOURCE_INFORMATION, |
- kMaxRenameRetries, |
- base::TimeTicks(), |
- callback); |
+ scoped_ptr<RenameParameters> parameters(new RenameParameters( |
+ ANNOTATE_WITH_SOURCE_INFORMATION, full_path, callback)); |
+ parameters->client_guid = client_guid; |
+ parameters->source_url = source_url; |
+ parameters->referrer_url = referrer_url; |
+ RenameWithRetryInternal(std::move(parameters)); |
} |
base::TimeDelta DownloadFileImpl::GetRetryDelayForFailedRename( |
@@ -140,16 +139,12 @@ bool DownloadFileImpl::ShouldRetryFailedRename(DownloadInterruptReason reason) { |
} |
void DownloadFileImpl::RenameWithRetryInternal( |
- const base::FilePath& full_path, |
- RenameOption option, |
- int retries_left, |
- base::TimeTicks time_of_first_failure, |
- const RenameCompletionCallback& callback) { |
+ scoped_ptr<RenameParameters> parameters) { |
DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
- base::FilePath new_path(full_path); |
+ base::FilePath new_path = parameters->new_path; |
- if ((option & UNIQUIFY) && full_path != file_.full_path()) { |
+ if ((parameters->option & UNIQUIFY) && new_path != file_.full_path()) { |
int uniquifier = |
base::GetUniquePathNumber(new_path, base::FilePath::StringType()); |
if (uniquifier > 0) |
@@ -165,36 +160,36 @@ void DownloadFileImpl::RenameWithRetryInternal( |
// have less assurance that the file at file_.full_path() was the one we were |
// working with. |
if (ShouldRetryFailedRename(reason) && file_.in_progress() && |
- retries_left > 0) { |
- int attempt_number = kMaxRenameRetries - retries_left; |
+ parameters->retries_left > 0) { |
+ int attempt_number = kMaxRenameRetries - parameters->retries_left; |
+ --parameters->retries_left; |
+ if (parameters->time_of_first_failure.is_null()) |
+ parameters->time_of_first_failure = base::TimeTicks::Now(); |
BrowserThread::PostDelayedTask( |
BrowserThread::FILE, |
FROM_HERE, |
base::Bind(&DownloadFileImpl::RenameWithRetryInternal, |
weak_factory_.GetWeakPtr(), |
- full_path, |
- option, |
- --retries_left, |
- time_of_first_failure.is_null() ? base::TimeTicks::Now() |
- : time_of_first_failure, |
- callback), |
+ base::Passed(std::move(parameters))), |
GetRetryDelayForFailedRename(attempt_number)); |
return; |
} |
- if (!time_of_first_failure.is_null()) |
+ if (!parameters->time_of_first_failure.is_null()) |
RecordDownloadFileRenameResultAfterRetry( |
- base::TimeTicks::Now() - time_of_first_failure, reason); |
+ base::TimeTicks::Now() - parameters->time_of_first_failure, reason); |
if (reason == DOWNLOAD_INTERRUPT_REASON_NONE && |
- (option & ANNOTATE_WITH_SOURCE_INFORMATION)) { |
+ (parameters->option & ANNOTATE_WITH_SOURCE_INFORMATION)) { |
// Doing the annotation after the rename rather than before leaves |
// a very small window during which the file has the final name but |
// hasn't been marked with the Mark Of The Web. However, it allows |
// anti-virus scanners on Windows to actually see the data |
// (http://crbug.com/127999) under the correct name (which is information |
// it uses). |
- reason = file_.AnnotateWithSourceInformation(); |
+ reason = file_.AnnotateWithSourceInformation(parameters->client_guid, |
+ parameters->source_url, |
+ parameters->referrer_url); |
} |
if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { |
@@ -209,8 +204,9 @@ void DownloadFileImpl::RenameWithRetryInternal( |
} |
BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(callback, reason, new_path)); |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(parameters->completion_callback, reason, new_path)); |
} |
void DownloadFileImpl::Detach() { |
@@ -221,7 +217,7 @@ void DownloadFileImpl::Cancel() { |
file_.Cancel(); |
} |
-base::FilePath DownloadFileImpl::FullPath() const { |
+const base::FilePath& DownloadFileImpl::FullPath() const { |
return file_.full_path(); |
} |
@@ -229,22 +225,6 @@ bool DownloadFileImpl::InProgress() const { |
return file_.in_progress(); |
} |
-int64_t DownloadFileImpl::CurrentSpeed() const { |
- return rate_estimator_.GetCountPerSecond(); |
-} |
- |
-bool DownloadFileImpl::GetHash(std::string* hash) { |
- return file_.GetHash(hash); |
-} |
- |
-std::string DownloadFileImpl::GetHashState() { |
- return file_.GetHashState(); |
-} |
- |
-void DownloadFileImpl::SetClientGuid(const std::string& guid) { |
- file_.SetClientGuid(guid); |
-} |
- |
void DownloadFileImpl::StreamActive() { |
base::TimeTicks start(base::TimeTicks::Now()); |
base::TimeTicks now; |
@@ -281,10 +261,6 @@ void DownloadFileImpl::StreamActive() { |
stream_reader_->GetStatus()); |
SendUpdate(); |
base::TimeTicks close_start(base::TimeTicks::Now()); |
- if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) |
- file_.Finish(); |
- else |
- file_.FinishWithError(); |
base::TimeTicks now(base::TimeTicks::Now()); |
disk_writes_time_ += (now - close_start); |
RecordFileBandwidth( |
@@ -322,24 +298,29 @@ void DownloadFileImpl::StreamActive() { |
// Our observer will clean us up. |
stream_reader_->RegisterCallback(base::Closure()); |
weak_factory_.InvalidateWeakPtrs(); |
- SendUpdate(); // Make info up to date before error. |
+ SendUpdate(); // Make info up to date before error. |
+ scoped_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
+ BrowserThread::UI, |
+ FROM_HERE, |
base::Bind(&DownloadDestinationObserver::DestinationError, |
- observer_, reason)); |
+ observer_, |
+ reason, |
+ file_.bytes_so_far(), |
+ base::Passed(&hash_state))); |
} else if (state == ByteStreamReader::STREAM_COMPLETE) { |
// Signal successful completion and shut down processing. |
stream_reader_->RegisterCallback(base::Closure()); |
weak_factory_.InvalidateWeakPtrs(); |
- std::string hash; |
- if (!GetHash(&hash) || file_.IsEmptyHash(hash)) |
- hash.clear(); |
SendUpdate(); |
+ scoped_ptr<crypto::SecureHash> hash_state = file_.Finish(); |
BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind( |
- &DownloadDestinationObserver::DestinationCompleted, |
- observer_, hash)); |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&DownloadDestinationObserver::DestinationCompleted, |
+ observer_, |
+ file_.bytes_so_far(), |
+ base::Passed(&hash_state))); |
} |
if (bound_net_log_.IsCapturing()) { |
bound_net_log_.AddEvent( |
@@ -351,15 +332,23 @@ void DownloadFileImpl::StreamActive() { |
void DownloadFileImpl::SendUpdate() { |
BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
+ BrowserThread::UI, |
+ FROM_HERE, |
base::Bind(&DownloadDestinationObserver::DestinationUpdate, |
- observer_, file_.bytes_so_far(), CurrentSpeed(), |
- GetHashState())); |
+ observer_, |
+ file_.bytes_so_far(), |
+ rate_estimator_.GetCountPerSecond())); |
} |
-// static |
-int DownloadFile::GetNumberOfDownloadFiles() { |
- return number_active_objects_; |
-} |
+DownloadFileImpl::RenameParameters::RenameParameters( |
+ RenameOption option, |
+ const base::FilePath& new_path, |
+ const RenameCompletionCallback& completion_callback) |
+ : option(option), |
+ new_path(new_path), |
+ retries_left(kMaxRenameRetries), |
+ completion_callback(completion_callback) {} |
+ |
+DownloadFileImpl::RenameParameters::~RenameParameters() {} |
} // namespace content |