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

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

Issue 1751603002: [Downloads] Rework how hashes are calculated for download files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address first round of comments Created 4 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
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/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "content/browser/byte_stream.h" 15 #include "content/browser/byte_stream.h"
16 #include "content/browser/download/download_create_info.h" 16 #include "content/browser/download/download_create_info.h"
17 #include "content/browser/download/download_destination_observer.h"
17 #include "content/browser/download/download_interrupt_reasons_impl.h" 18 #include "content/browser/download/download_interrupt_reasons_impl.h"
18 #include "content/browser/download/download_net_log_parameters.h" 19 #include "content/browser/download/download_net_log_parameters.h"
19 #include "content/browser/download/download_stats.h" 20 #include "content/browser/download/download_stats.h"
20 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/download_destination_observer.h" 22 #include "crypto/secure_hash.h"
23 #include "crypto/sha2.h"
22 #include "net/base/io_buffer.h" 24 #include "net/base/io_buffer.h"
23 25
24 namespace content { 26 namespace content {
25 27
26 const int kUpdatePeriodMs = 500; 28 const int kUpdatePeriodMs = 500;
27 const int kMaxTimeBlockingFileThreadMs = 1000; 29 const int kMaxTimeBlockingFileThreadMs = 1000;
28 30
29 // These constants control the default retry behavior for failing renames. Each 31 // These constants control the default retry behavior for failing renames. Each
30 // retry is performed after a delay that is twice the previous delay. The 32 // retry is performed after a delay that is twice the previous delay. The
31 // initial delay is specified by kInitialRenameRetryDelayMs. 33 // initial delay is specified by kInitialRenameRetryDelayMs.
32 const int kMaxRenameRetries = 3;
33 const int kInitialRenameRetryDelayMs = 200; 34 const int kInitialRenameRetryDelayMs = 200;
34 35
35 int DownloadFile::number_active_objects_ = 0; 36 // Number of times a failing rename is retried before giving up.
37 const int kMaxRenameRetries = 3;
36 38
37 DownloadFileImpl::DownloadFileImpl( 39 DownloadFileImpl::DownloadFileImpl(
38 const DownloadSaveInfo& save_info, 40 scoped_ptr<DownloadSaveInfo> save_info,
39 const base::FilePath& default_download_directory, 41 const base::FilePath& default_download_directory,
40 const GURL& url,
41 const GURL& referrer_url,
42 bool calculate_hash,
43 base::File file,
44 scoped_ptr<ByteStreamReader> stream, 42 scoped_ptr<ByteStreamReader> stream,
45 const net::BoundNetLog& bound_net_log, 43 const net::BoundNetLog& bound_net_log,
46 base::WeakPtr<DownloadDestinationObserver> observer) 44 base::WeakPtr<DownloadDestinationObserver> observer)
47 : file_(save_info.file_path, 45 : file_(bound_net_log),
48 url, 46 save_info_(std::move(save_info)),
49 referrer_url,
50 save_info.offset,
51 calculate_hash,
52 save_info.hash_state,
53 std::move(file),
54 bound_net_log),
55 default_download_directory_(default_download_directory), 47 default_download_directory_(default_download_directory),
56 stream_reader_(std::move(stream)), 48 stream_reader_(std::move(stream)),
57 bytes_seen_(0), 49 bytes_seen_(0),
58 bound_net_log_(bound_net_log), 50 bound_net_log_(bound_net_log),
59 observer_(observer), 51 observer_(observer),
60 weak_factory_(this) {} 52 weak_factory_(this) {}
61 53
62 DownloadFileImpl::~DownloadFileImpl() { 54 DownloadFileImpl::~DownloadFileImpl() {
63 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 55 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
64 --number_active_objects_;
65 } 56 }
66 57
67 void DownloadFileImpl::Initialize(const InitializeCallback& callback) { 58 void DownloadFileImpl::Initialize(const InitializeCallback& callback) {
68 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 59 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
69 60
70 update_timer_.reset(new base::RepeatingTimer()); 61 update_timer_.reset(new base::RepeatingTimer());
71 DownloadInterruptReason result = 62 DownloadInterruptReason result = file_.Initialize(
72 file_.Initialize(default_download_directory_); 63 save_info_->file_path, default_download_directory_,
64 std::move(save_info_->file), save_info_->offset, save_info_->prefix_hash,
65 std::move(save_info_->hash_state));
73 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { 66 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) {
74 BrowserThread::PostTask( 67 BrowserThread::PostTask(
75 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); 68 BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
76 return; 69 return;
77 } 70 }
78 71
79 stream_reader_->RegisterCallback( 72 stream_reader_->RegisterCallback(
80 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr())); 73 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr()));
81 74
82 download_start_ = base::TimeTicks::Now(); 75 download_start_ = base::TimeTicks::Now();
83 76
84 // Primarily to make reset to zero in restart visible to owner. 77 // Primarily to make reset to zero in restart visible to owner.
85 SendUpdate(); 78 SendUpdate();
86 79
87 // Initial pull from the straw. 80 // Initial pull from the straw.
88 StreamActive(); 81 StreamActive();
89 82
90 BrowserThread::PostTask( 83 BrowserThread::PostTask(
91 BrowserThread::UI, FROM_HERE, base::Bind( 84 BrowserThread::UI, FROM_HERE, base::Bind(
92 callback, DOWNLOAD_INTERRUPT_REASON_NONE)); 85 callback, DOWNLOAD_INTERRUPT_REASON_NONE));
93
94 ++number_active_objects_;
95 } 86 }
96 87
97 DownloadInterruptReason DownloadFileImpl::AppendDataToFile( 88 DownloadInterruptReason DownloadFileImpl::AppendDataToFile(
98 const char* data, size_t data_len) { 89 const char* data, size_t data_len) {
99 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 90 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
100 91
101 if (!update_timer_->IsRunning()) { 92 if (!update_timer_->IsRunning()) {
102 update_timer_->Start(FROM_HERE, 93 update_timer_->Start(FROM_HERE,
103 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 94 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
104 this, &DownloadFileImpl::SendUpdate); 95 this, &DownloadFileImpl::SendUpdate);
105 } 96 }
106 rate_estimator_.Increment(data_len); 97 rate_estimator_.Increment(data_len);
107 return file_.AppendDataToFile(data, data_len); 98 return file_.AppendDataToFile(data, data_len);
108 } 99 }
109 100
110 void DownloadFileImpl::RenameAndUniquify( 101 void DownloadFileImpl::RenameAndUniquify(
111 const base::FilePath& full_path, 102 const base::FilePath& full_path,
112 const RenameCompletionCallback& callback) { 103 const RenameCompletionCallback& callback) {
113 RenameWithRetryInternal( 104 scoped_ptr<RenameParameters> parameters(
114 full_path, UNIQUIFY, kMaxRenameRetries, base::TimeTicks(), callback); 105 new RenameParameters(UNIQUIFY, full_path, callback));
106 RenameWithRetryInternal(std::move(parameters));
115 } 107 }
116 108
117 void DownloadFileImpl::RenameAndAnnotate( 109 void DownloadFileImpl::RenameAndAnnotate(
118 const base::FilePath& full_path, 110 const base::FilePath& full_path,
111 const std::string& client_guid,
112 const GURL& source_url,
113 const GURL& referrer_url,
119 const RenameCompletionCallback& callback) { 114 const RenameCompletionCallback& callback) {
120 RenameWithRetryInternal(full_path, 115 scoped_ptr<RenameParameters> parameters(new RenameParameters(
121 ANNOTATE_WITH_SOURCE_INFORMATION, 116 ANNOTATE_WITH_SOURCE_INFORMATION, full_path, callback));
122 kMaxRenameRetries, 117 parameters->client_guid = client_guid;
123 base::TimeTicks(), 118 parameters->source_url = source_url;
124 callback); 119 parameters->referrer_url = referrer_url;
120 RenameWithRetryInternal(std::move(parameters));
125 } 121 }
126 122
127 base::TimeDelta DownloadFileImpl::GetRetryDelayForFailedRename( 123 base::TimeDelta DownloadFileImpl::GetRetryDelayForFailedRename(
128 int attempt_number) { 124 int attempt_number) {
129 DCHECK_GE(attempt_number, 0); 125 DCHECK_GE(attempt_number, 0);
130 // |delay| starts at kInitialRenameRetryDelayMs and increases by a factor of 126 // |delay| starts at kInitialRenameRetryDelayMs and increases by a factor of
131 // 2 at each subsequent retry. Assumes that |retries_left| starts at 127 // 2 at each subsequent retry. Assumes that |retries_left| starts at
132 // kMaxRenameRetries. Also assumes that kMaxRenameRetries is less than the 128 // kMaxRenameRetries. Also assumes that kMaxRenameRetries is less than the
133 // number of bits in an int. 129 // number of bits in an int.
134 return base::TimeDelta::FromMilliseconds(kInitialRenameRetryDelayMs) * 130 return base::TimeDelta::FromMilliseconds(kInitialRenameRetryDelayMs) *
135 (1 << attempt_number); 131 (1 << attempt_number);
136 } 132 }
137 133
138 bool DownloadFileImpl::ShouldRetryFailedRename(DownloadInterruptReason reason) { 134 bool DownloadFileImpl::ShouldRetryFailedRename(DownloadInterruptReason reason) {
139 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR; 135 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR;
140 } 136 }
141 137
142 void DownloadFileImpl::RenameWithRetryInternal( 138 void DownloadFileImpl::RenameWithRetryInternal(
143 const base::FilePath& full_path, 139 scoped_ptr<RenameParameters> parameters) {
144 RenameOption option,
145 int retries_left,
146 base::TimeTicks time_of_first_failure,
147 const RenameCompletionCallback& callback) {
148 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 140 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
149 141
150 base::FilePath new_path(full_path); 142 base::FilePath new_path = parameters->new_path;
151 143
152 if ((option & UNIQUIFY) && full_path != file_.full_path()) { 144 if ((parameters->option & UNIQUIFY) && new_path != file_.full_path()) {
153 int uniquifier = 145 int uniquifier =
154 base::GetUniquePathNumber(new_path, base::FilePath::StringType()); 146 base::GetUniquePathNumber(new_path, base::FilePath::StringType());
155 if (uniquifier > 0) 147 if (uniquifier > 0)
156 new_path = new_path.InsertBeforeExtensionASCII( 148 new_path = new_path.InsertBeforeExtensionASCII(
157 base::StringPrintf(" (%d)", uniquifier)); 149 base::StringPrintf(" (%d)", uniquifier));
158 } 150 }
159 151
160 DownloadInterruptReason reason = file_.Rename(new_path); 152 DownloadInterruptReason reason = file_.Rename(new_path);
161 153
162 // Attempt to retry the rename if possible. If the rename failed and the 154 // Attempt to retry the rename if possible. If the rename failed and the
163 // subsequent open also failed, then in_progress() would be false. We don't 155 // subsequent open also failed, then in_progress() would be false. We don't
164 // try to retry renames if the in_progress() was false to begin with since we 156 // try to retry renames if the in_progress() was false to begin with since we
165 // have less assurance that the file at file_.full_path() was the one we were 157 // have less assurance that the file at file_.full_path() was the one we were
166 // working with. 158 // working with.
167 if (ShouldRetryFailedRename(reason) && file_.in_progress() && 159 if (ShouldRetryFailedRename(reason) && file_.in_progress() &&
168 retries_left > 0) { 160 parameters->retries_left > 0) {
169 int attempt_number = kMaxRenameRetries - retries_left; 161 int attempt_number = kMaxRenameRetries - parameters->retries_left;
162 --parameters->retries_left;
163 if (parameters->time_of_first_failure.is_null())
164 parameters->time_of_first_failure = base::TimeTicks::Now();
170 BrowserThread::PostDelayedTask( 165 BrowserThread::PostDelayedTask(
171 BrowserThread::FILE, 166 BrowserThread::FILE, FROM_HERE,
172 FROM_HERE,
173 base::Bind(&DownloadFileImpl::RenameWithRetryInternal, 167 base::Bind(&DownloadFileImpl::RenameWithRetryInternal,
174 weak_factory_.GetWeakPtr(), 168 weak_factory_.GetWeakPtr(),
175 full_path, 169 base::Passed(std::move(parameters))),
176 option,
177 --retries_left,
178 time_of_first_failure.is_null() ? base::TimeTicks::Now()
179 : time_of_first_failure,
180 callback),
181 GetRetryDelayForFailedRename(attempt_number)); 170 GetRetryDelayForFailedRename(attempt_number));
182 return; 171 return;
183 } 172 }
184 173
185 if (!time_of_first_failure.is_null()) 174 if (!parameters->time_of_first_failure.is_null())
186 RecordDownloadFileRenameResultAfterRetry( 175 RecordDownloadFileRenameResultAfterRetry(
187 base::TimeTicks::Now() - time_of_first_failure, reason); 176 base::TimeTicks::Now() - parameters->time_of_first_failure, reason);
188 177
189 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE && 178 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE &&
190 (option & ANNOTATE_WITH_SOURCE_INFORMATION)) { 179 (parameters->option & ANNOTATE_WITH_SOURCE_INFORMATION)) {
191 // Doing the annotation after the rename rather than before leaves 180 // Doing the annotation after the rename rather than before leaves
192 // a very small window during which the file has the final name but 181 // a very small window during which the file has the final name but
193 // hasn't been marked with the Mark Of The Web. However, it allows 182 // hasn't been marked with the Mark Of The Web. However, it allows
194 // anti-virus scanners on Windows to actually see the data 183 // anti-virus scanners on Windows to actually see the data
195 // (http://crbug.com/127999) under the correct name (which is information 184 // (http://crbug.com/127999) under the correct name (which is information
196 // it uses). 185 // it uses).
197 reason = file_.AnnotateWithSourceInformation(); 186 reason = file_.AnnotateWithSourceInformation(parameters->client_guid,
187 parameters->source_url,
188 parameters->referrer_url);
198 } 189 }
199 190
200 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { 191 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
201 // Make sure our information is updated, since we're about to 192 // Make sure our information is updated, since we're about to
202 // error out. 193 // error out.
203 SendUpdate(); 194 SendUpdate();
204 195
205 // Null out callback so that we don't do any more stream processing. 196 // Null out callback so that we don't do any more stream processing.
206 stream_reader_->RegisterCallback(base::Closure()); 197 stream_reader_->RegisterCallback(base::Closure());
207 198
208 new_path.clear(); 199 new_path.clear();
209 } 200 }
210 201
211 BrowserThread::PostTask( 202 BrowserThread::PostTask(
212 BrowserThread::UI, FROM_HERE, 203 BrowserThread::UI, FROM_HERE,
213 base::Bind(callback, reason, new_path)); 204 base::Bind(parameters->completion_callback, reason, new_path));
214 } 205 }
215 206
216 void DownloadFileImpl::Detach() { 207 void DownloadFileImpl::Detach() {
217 file_.Detach(); 208 file_.Detach();
218 } 209 }
219 210
220 void DownloadFileImpl::Cancel() { 211 void DownloadFileImpl::Cancel() {
221 file_.Cancel(); 212 file_.Cancel();
222 } 213 }
223 214
224 base::FilePath DownloadFileImpl::FullPath() const { 215 const base::FilePath& DownloadFileImpl::FullPath() const {
225 return file_.full_path(); 216 return file_.full_path();
226 } 217 }
227 218
228 bool DownloadFileImpl::InProgress() const { 219 bool DownloadFileImpl::InProgress() const {
229 return file_.in_progress(); 220 return file_.in_progress();
230 } 221 }
231 222
232 int64_t DownloadFileImpl::CurrentSpeed() const {
233 return rate_estimator_.GetCountPerSecond();
234 }
235
236 bool DownloadFileImpl::GetHash(std::string* hash) {
237 return file_.GetHash(hash);
238 }
239
240 std::string DownloadFileImpl::GetHashState() {
241 return file_.GetHashState();
242 }
243
244 void DownloadFileImpl::SetClientGuid(const std::string& guid) {
245 file_.SetClientGuid(guid);
246 }
247
248 void DownloadFileImpl::StreamActive() { 223 void DownloadFileImpl::StreamActive() {
249 base::TimeTicks start(base::TimeTicks::Now()); 224 base::TimeTicks start(base::TimeTicks::Now());
250 base::TimeTicks now; 225 base::TimeTicks now;
251 scoped_refptr<net::IOBuffer> incoming_data; 226 scoped_refptr<net::IOBuffer> incoming_data;
252 size_t incoming_data_size = 0; 227 size_t incoming_data_size = 0;
253 size_t total_incoming_data_size = 0; 228 size_t total_incoming_data_size = 0;
254 size_t num_buffers = 0; 229 size_t num_buffers = 0;
255 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); 230 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY);
256 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; 231 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE;
257 base::TimeDelta delta( 232 base::TimeDelta delta(
(...skipping 16 matching lines...) Expand all
274 bytes_seen_ += incoming_data_size; 249 bytes_seen_ += incoming_data_size;
275 total_incoming_data_size += incoming_data_size; 250 total_incoming_data_size += incoming_data_size;
276 } 251 }
277 break; 252 break;
278 case ByteStreamReader::STREAM_COMPLETE: 253 case ByteStreamReader::STREAM_COMPLETE:
279 { 254 {
280 reason = static_cast<DownloadInterruptReason>( 255 reason = static_cast<DownloadInterruptReason>(
281 stream_reader_->GetStatus()); 256 stream_reader_->GetStatus());
282 SendUpdate(); 257 SendUpdate();
283 base::TimeTicks close_start(base::TimeTicks::Now()); 258 base::TimeTicks close_start(base::TimeTicks::Now());
284 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE)
285 file_.Finish();
286 else
287 file_.FinishWithError();
288 base::TimeTicks now(base::TimeTicks::Now()); 259 base::TimeTicks now(base::TimeTicks::Now());
289 disk_writes_time_ += (now - close_start); 260 disk_writes_time_ += (now - close_start);
290 RecordFileBandwidth( 261 RecordFileBandwidth(
291 bytes_seen_, disk_writes_time_, now - download_start_); 262 bytes_seen_, disk_writes_time_, now - download_start_);
292 update_timer_.reset(); 263 update_timer_.reset();
293 } 264 }
294 break; 265 break;
295 default: 266 default:
296 NOTREACHED(); 267 NOTREACHED();
297 break; 268 break;
(...skipping 17 matching lines...) Expand all
315 286
316 RecordContiguousWriteTime(now - start); 287 RecordContiguousWriteTime(now - start);
317 288
318 // Take care of communication with our observer. 289 // Take care of communication with our observer.
319 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { 290 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
320 // Error case for both upstream source and file write. 291 // Error case for both upstream source and file write.
321 // Shut down processing and signal an error to our observer. 292 // Shut down processing and signal an error to our observer.
322 // Our observer will clean us up. 293 // Our observer will clean us up.
323 stream_reader_->RegisterCallback(base::Closure()); 294 stream_reader_->RegisterCallback(base::Closure());
324 weak_factory_.InvalidateWeakPtrs(); 295 weak_factory_.InvalidateWeakPtrs();
325 SendUpdate(); // Make info up to date before error. 296 SendUpdate(); // Make info up to date before error.
297 scoped_ptr<crypto::SecureHash> hash_state = file_.Finish();
326 BrowserThread::PostTask( 298 BrowserThread::PostTask(
327 BrowserThread::UI, FROM_HERE, 299 BrowserThread::UI, FROM_HERE,
328 base::Bind(&DownloadDestinationObserver::DestinationError, 300 base::Bind(&DownloadDestinationObserver::DestinationError, observer_,
329 observer_, reason)); 301 reason, file_.bytes_so_far(), base::Passed(&hash_state)));
330 } else if (state == ByteStreamReader::STREAM_COMPLETE) { 302 } else if (state == ByteStreamReader::STREAM_COMPLETE) {
331 // Signal successful completion and shut down processing. 303 // Signal successful completion and shut down processing.
332 stream_reader_->RegisterCallback(base::Closure()); 304 stream_reader_->RegisterCallback(base::Closure());
333 weak_factory_.InvalidateWeakPtrs(); 305 weak_factory_.InvalidateWeakPtrs();
334 std::string hash;
335 if (!GetHash(&hash) || file_.IsEmptyHash(hash))
336 hash.clear();
337 SendUpdate(); 306 SendUpdate();
307 scoped_ptr<crypto::SecureHash> hash_state = file_.Finish();
338 BrowserThread::PostTask( 308 BrowserThread::PostTask(
339 BrowserThread::UI, FROM_HERE, 309 BrowserThread::UI, FROM_HERE,
340 base::Bind( 310 base::Bind(&DownloadDestinationObserver::DestinationCompleted,
341 &DownloadDestinationObserver::DestinationCompleted, 311 observer_, file_.bytes_so_far(), base::Passed(&hash_state)));
342 observer_, hash));
343 } 312 }
344 if (bound_net_log_.IsCapturing()) { 313 if (bound_net_log_.IsCapturing()) {
345 bound_net_log_.AddEvent( 314 bound_net_log_.AddEvent(
346 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED, 315 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED,
347 base::Bind(&FileStreamDrainedNetLogCallback, total_incoming_data_size, 316 base::Bind(&FileStreamDrainedNetLogCallback, total_incoming_data_size,
348 num_buffers)); 317 num_buffers));
349 } 318 }
350 } 319 }
351 320
352 void DownloadFileImpl::SendUpdate() { 321 void DownloadFileImpl::SendUpdate() {
353 BrowserThread::PostTask( 322 BrowserThread::PostTask(
354 BrowserThread::UI, FROM_HERE, 323 BrowserThread::UI, FROM_HERE,
355 base::Bind(&DownloadDestinationObserver::DestinationUpdate, 324 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_,
356 observer_, file_.bytes_so_far(), CurrentSpeed(), 325 file_.bytes_so_far(), rate_estimator_.GetCountPerSecond()));
357 GetHashState()));
358 } 326 }
359 327
360 // static 328 DownloadFileImpl::RenameParameters::RenameParameters(
361 int DownloadFile::GetNumberOfDownloadFiles() { 329 RenameOption option,
362 return number_active_objects_; 330 const base::FilePath& new_path,
363 } 331 const RenameCompletionCallback& completion_callback)
332 : option(option),
333 new_path(new_path),
334 retries_left(kMaxRenameRetries),
335 completion_callback(completion_callback) {}
336
337 DownloadFileImpl::RenameParameters::~RenameParameters() {}
364 338
365 } // namespace content 339 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698