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

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: Rebase on top of https://codereview.chromium.org/1781983002 since that's going in first. 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 =
72 file_.Initialize(default_download_directory_); 63 file_.Initialize(save_info_->file_path,
64 default_download_directory_,
65 std::move(save_info_->file),
66 save_info_->offset,
67 save_info_->hash_of_partial_file,
68 std::move(save_info_->hash_state));
73 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { 69 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) {
74 BrowserThread::PostTask( 70 BrowserThread::PostTask(
75 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); 71 BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
76 return; 72 return;
77 } 73 }
78 74
79 stream_reader_->RegisterCallback( 75 stream_reader_->RegisterCallback(
80 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr())); 76 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr()));
81 77
82 download_start_ = base::TimeTicks::Now(); 78 download_start_ = base::TimeTicks::Now();
83 79
84 // Primarily to make reset to zero in restart visible to owner. 80 // Primarily to make reset to zero in restart visible to owner.
85 SendUpdate(); 81 SendUpdate();
86 82
87 // Initial pull from the straw. 83 // Initial pull from the straw.
88 StreamActive(); 84 StreamActive();
89 85
90 BrowserThread::PostTask( 86 BrowserThread::PostTask(
91 BrowserThread::UI, FROM_HERE, base::Bind( 87 BrowserThread::UI, FROM_HERE, base::Bind(
92 callback, DOWNLOAD_INTERRUPT_REASON_NONE)); 88 callback, DOWNLOAD_INTERRUPT_REASON_NONE));
93
94 ++number_active_objects_;
95 } 89 }
96 90
97 DownloadInterruptReason DownloadFileImpl::AppendDataToFile( 91 DownloadInterruptReason DownloadFileImpl::AppendDataToFile(
98 const char* data, size_t data_len) { 92 const char* data, size_t data_len) {
99 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 93 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
100 94
101 if (!update_timer_->IsRunning()) { 95 if (!update_timer_->IsRunning()) {
102 update_timer_->Start(FROM_HERE, 96 update_timer_->Start(FROM_HERE,
103 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 97 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
104 this, &DownloadFileImpl::SendUpdate); 98 this, &DownloadFileImpl::SendUpdate);
105 } 99 }
106 rate_estimator_.Increment(data_len); 100 rate_estimator_.Increment(data_len);
107 return file_.AppendDataToFile(data, data_len); 101 return file_.AppendDataToFile(data, data_len);
108 } 102 }
109 103
110 void DownloadFileImpl::RenameAndUniquify( 104 void DownloadFileImpl::RenameAndUniquify(
111 const base::FilePath& full_path, 105 const base::FilePath& full_path,
112 const RenameCompletionCallback& callback) { 106 const RenameCompletionCallback& callback) {
113 RenameWithRetryInternal( 107 scoped_ptr<RenameParameters> parameters(
114 full_path, UNIQUIFY, kMaxRenameRetries, base::TimeTicks(), callback); 108 new RenameParameters(UNIQUIFY, full_path, callback));
109 RenameWithRetryInternal(std::move(parameters));
115 } 110 }
116 111
117 void DownloadFileImpl::RenameAndAnnotate( 112 void DownloadFileImpl::RenameAndAnnotate(
118 const base::FilePath& full_path, 113 const base::FilePath& full_path,
114 const std::string& client_guid,
115 const GURL& source_url,
116 const GURL& referrer_url,
119 const RenameCompletionCallback& callback) { 117 const RenameCompletionCallback& callback) {
120 RenameWithRetryInternal(full_path, 118 scoped_ptr<RenameParameters> parameters(new RenameParameters(
121 ANNOTATE_WITH_SOURCE_INFORMATION, 119 ANNOTATE_WITH_SOURCE_INFORMATION, full_path, callback));
122 kMaxRenameRetries, 120 parameters->client_guid = client_guid;
123 base::TimeTicks(), 121 parameters->source_url = source_url;
124 callback); 122 parameters->referrer_url = referrer_url;
123 RenameWithRetryInternal(std::move(parameters));
125 } 124 }
126 125
127 base::TimeDelta DownloadFileImpl::GetRetryDelayForFailedRename( 126 base::TimeDelta DownloadFileImpl::GetRetryDelayForFailedRename(
128 int attempt_number) { 127 int attempt_number) {
129 DCHECK_GE(attempt_number, 0); 128 DCHECK_GE(attempt_number, 0);
130 // |delay| starts at kInitialRenameRetryDelayMs and increases by a factor of 129 // |delay| starts at kInitialRenameRetryDelayMs and increases by a factor of
131 // 2 at each subsequent retry. Assumes that |retries_left| starts at 130 // 2 at each subsequent retry. Assumes that |retries_left| starts at
132 // kMaxRenameRetries. Also assumes that kMaxRenameRetries is less than the 131 // kMaxRenameRetries. Also assumes that kMaxRenameRetries is less than the
133 // number of bits in an int. 132 // number of bits in an int.
134 return base::TimeDelta::FromMilliseconds(kInitialRenameRetryDelayMs) * 133 return base::TimeDelta::FromMilliseconds(kInitialRenameRetryDelayMs) *
135 (1 << attempt_number); 134 (1 << attempt_number);
136 } 135 }
137 136
138 bool DownloadFileImpl::ShouldRetryFailedRename(DownloadInterruptReason reason) { 137 bool DownloadFileImpl::ShouldRetryFailedRename(DownloadInterruptReason reason) {
139 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR; 138 return reason == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR;
140 } 139 }
141 140
142 void DownloadFileImpl::RenameWithRetryInternal( 141 void DownloadFileImpl::RenameWithRetryInternal(
143 const base::FilePath& full_path, 142 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); 143 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
149 144
150 base::FilePath new_path(full_path); 145 base::FilePath new_path = parameters->new_path;
151 146
152 if ((option & UNIQUIFY) && full_path != file_.full_path()) { 147 if ((parameters->option & UNIQUIFY) && new_path != file_.full_path()) {
153 int uniquifier = 148 int uniquifier =
154 base::GetUniquePathNumber(new_path, base::FilePath::StringType()); 149 base::GetUniquePathNumber(new_path, base::FilePath::StringType());
155 if (uniquifier > 0) 150 if (uniquifier > 0)
156 new_path = new_path.InsertBeforeExtensionASCII( 151 new_path = new_path.InsertBeforeExtensionASCII(
157 base::StringPrintf(" (%d)", uniquifier)); 152 base::StringPrintf(" (%d)", uniquifier));
158 } 153 }
159 154
160 DownloadInterruptReason reason = file_.Rename(new_path); 155 DownloadInterruptReason reason = file_.Rename(new_path);
161 156
162 // Attempt to retry the rename if possible. If the rename failed and the 157 // 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 158 // 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 159 // 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 160 // have less assurance that the file at file_.full_path() was the one we were
166 // working with. 161 // working with.
167 if (ShouldRetryFailedRename(reason) && file_.in_progress() && 162 if (ShouldRetryFailedRename(reason) && file_.in_progress() &&
168 retries_left > 0) { 163 parameters->retries_left > 0) {
169 int attempt_number = kMaxRenameRetries - retries_left; 164 int attempt_number = kMaxRenameRetries - parameters->retries_left;
165 --parameters->retries_left;
166 if (parameters->time_of_first_failure.is_null())
167 parameters->time_of_first_failure = base::TimeTicks::Now();
170 BrowserThread::PostDelayedTask( 168 BrowserThread::PostDelayedTask(
171 BrowserThread::FILE, 169 BrowserThread::FILE,
172 FROM_HERE, 170 FROM_HERE,
173 base::Bind(&DownloadFileImpl::RenameWithRetryInternal, 171 base::Bind(&DownloadFileImpl::RenameWithRetryInternal,
174 weak_factory_.GetWeakPtr(), 172 weak_factory_.GetWeakPtr(),
175 full_path, 173 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)); 174 GetRetryDelayForFailedRename(attempt_number));
182 return; 175 return;
183 } 176 }
184 177
185 if (!time_of_first_failure.is_null()) 178 if (!parameters->time_of_first_failure.is_null())
186 RecordDownloadFileRenameResultAfterRetry( 179 RecordDownloadFileRenameResultAfterRetry(
187 base::TimeTicks::Now() - time_of_first_failure, reason); 180 base::TimeTicks::Now() - parameters->time_of_first_failure, reason);
188 181
189 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE && 182 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE &&
190 (option & ANNOTATE_WITH_SOURCE_INFORMATION)) { 183 (parameters->option & ANNOTATE_WITH_SOURCE_INFORMATION)) {
191 // Doing the annotation after the rename rather than before leaves 184 // Doing the annotation after the rename rather than before leaves
192 // a very small window during which the file has the final name but 185 // 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 186 // hasn't been marked with the Mark Of The Web. However, it allows
194 // anti-virus scanners on Windows to actually see the data 187 // anti-virus scanners on Windows to actually see the data
195 // (http://crbug.com/127999) under the correct name (which is information 188 // (http://crbug.com/127999) under the correct name (which is information
196 // it uses). 189 // it uses).
197 reason = file_.AnnotateWithSourceInformation(); 190 reason = file_.AnnotateWithSourceInformation(parameters->client_guid,
191 parameters->source_url,
192 parameters->referrer_url);
198 } 193 }
199 194
200 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { 195 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
201 // Make sure our information is updated, since we're about to 196 // Make sure our information is updated, since we're about to
202 // error out. 197 // error out.
203 SendUpdate(); 198 SendUpdate();
204 199
205 // Null out callback so that we don't do any more stream processing. 200 // Null out callback so that we don't do any more stream processing.
206 stream_reader_->RegisterCallback(base::Closure()); 201 stream_reader_->RegisterCallback(base::Closure());
207 202
208 new_path.clear(); 203 new_path.clear();
209 } 204 }
210 205
211 BrowserThread::PostTask( 206 BrowserThread::PostTask(
212 BrowserThread::UI, FROM_HERE, 207 BrowserThread::UI,
213 base::Bind(callback, reason, new_path)); 208 FROM_HERE,
209 base::Bind(parameters->completion_callback, reason, new_path));
214 } 210 }
215 211
216 void DownloadFileImpl::Detach() { 212 void DownloadFileImpl::Detach() {
217 file_.Detach(); 213 file_.Detach();
218 } 214 }
219 215
220 void DownloadFileImpl::Cancel() { 216 void DownloadFileImpl::Cancel() {
221 file_.Cancel(); 217 file_.Cancel();
222 } 218 }
223 219
224 base::FilePath DownloadFileImpl::FullPath() const { 220 const base::FilePath& DownloadFileImpl::FullPath() const {
225 return file_.full_path(); 221 return file_.full_path();
226 } 222 }
227 223
228 bool DownloadFileImpl::InProgress() const { 224 bool DownloadFileImpl::InProgress() const {
229 return file_.in_progress(); 225 return file_.in_progress();
230 } 226 }
231 227
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() { 228 void DownloadFileImpl::StreamActive() {
249 base::TimeTicks start(base::TimeTicks::Now()); 229 base::TimeTicks start(base::TimeTicks::Now());
250 base::TimeTicks now; 230 base::TimeTicks now;
251 scoped_refptr<net::IOBuffer> incoming_data; 231 scoped_refptr<net::IOBuffer> incoming_data;
252 size_t incoming_data_size = 0; 232 size_t incoming_data_size = 0;
253 size_t total_incoming_data_size = 0; 233 size_t total_incoming_data_size = 0;
254 size_t num_buffers = 0; 234 size_t num_buffers = 0;
255 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); 235 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY);
256 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; 236 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE;
257 base::TimeDelta delta( 237 base::TimeDelta delta(
(...skipping 16 matching lines...) Expand all
274 bytes_seen_ += incoming_data_size; 254 bytes_seen_ += incoming_data_size;
275 total_incoming_data_size += incoming_data_size; 255 total_incoming_data_size += incoming_data_size;
276 } 256 }
277 break; 257 break;
278 case ByteStreamReader::STREAM_COMPLETE: 258 case ByteStreamReader::STREAM_COMPLETE:
279 { 259 {
280 reason = static_cast<DownloadInterruptReason>( 260 reason = static_cast<DownloadInterruptReason>(
281 stream_reader_->GetStatus()); 261 stream_reader_->GetStatus());
282 SendUpdate(); 262 SendUpdate();
283 base::TimeTicks close_start(base::TimeTicks::Now()); 263 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()); 264 base::TimeTicks now(base::TimeTicks::Now());
289 disk_writes_time_ += (now - close_start); 265 disk_writes_time_ += (now - close_start);
290 RecordFileBandwidth( 266 RecordFileBandwidth(
291 bytes_seen_, disk_writes_time_, now - download_start_); 267 bytes_seen_, disk_writes_time_, now - download_start_);
292 update_timer_.reset(); 268 update_timer_.reset();
293 } 269 }
294 break; 270 break;
295 default: 271 default:
296 NOTREACHED(); 272 NOTREACHED();
297 break; 273 break;
(...skipping 17 matching lines...) Expand all
315 291
316 RecordContiguousWriteTime(now - start); 292 RecordContiguousWriteTime(now - start);
317 293
318 // Take care of communication with our observer. 294 // Take care of communication with our observer.
319 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { 295 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
320 // Error case for both upstream source and file write. 296 // Error case for both upstream source and file write.
321 // Shut down processing and signal an error to our observer. 297 // Shut down processing and signal an error to our observer.
322 // Our observer will clean us up. 298 // Our observer will clean us up.
323 stream_reader_->RegisterCallback(base::Closure()); 299 stream_reader_->RegisterCallback(base::Closure());
324 weak_factory_.InvalidateWeakPtrs(); 300 weak_factory_.InvalidateWeakPtrs();
325 SendUpdate(); // Make info up to date before error. 301 SendUpdate(); // Make info up to date before error.
302 scoped_ptr<crypto::SecureHash> hash_state = file_.Finish();
326 BrowserThread::PostTask( 303 BrowserThread::PostTask(
327 BrowserThread::UI, FROM_HERE, 304 BrowserThread::UI,
305 FROM_HERE,
328 base::Bind(&DownloadDestinationObserver::DestinationError, 306 base::Bind(&DownloadDestinationObserver::DestinationError,
329 observer_, reason)); 307 observer_,
308 reason,
309 file_.bytes_so_far(),
310 base::Passed(&hash_state)));
330 } else if (state == ByteStreamReader::STREAM_COMPLETE) { 311 } else if (state == ByteStreamReader::STREAM_COMPLETE) {
331 // Signal successful completion and shut down processing. 312 // Signal successful completion and shut down processing.
332 stream_reader_->RegisterCallback(base::Closure()); 313 stream_reader_->RegisterCallback(base::Closure());
333 weak_factory_.InvalidateWeakPtrs(); 314 weak_factory_.InvalidateWeakPtrs();
334 std::string hash;
335 if (!GetHash(&hash) || file_.IsEmptyHash(hash))
336 hash.clear();
337 SendUpdate(); 315 SendUpdate();
316 scoped_ptr<crypto::SecureHash> hash_state = file_.Finish();
338 BrowserThread::PostTask( 317 BrowserThread::PostTask(
339 BrowserThread::UI, FROM_HERE, 318 BrowserThread::UI,
340 base::Bind( 319 FROM_HERE,
341 &DownloadDestinationObserver::DestinationCompleted, 320 base::Bind(&DownloadDestinationObserver::DestinationCompleted,
342 observer_, hash)); 321 observer_,
322 file_.bytes_so_far(),
323 base::Passed(&hash_state)));
343 } 324 }
344 if (bound_net_log_.IsCapturing()) { 325 if (bound_net_log_.IsCapturing()) {
345 bound_net_log_.AddEvent( 326 bound_net_log_.AddEvent(
346 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED, 327 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED,
347 base::Bind(&FileStreamDrainedNetLogCallback, total_incoming_data_size, 328 base::Bind(&FileStreamDrainedNetLogCallback, total_incoming_data_size,
348 num_buffers)); 329 num_buffers));
349 } 330 }
350 } 331 }
351 332
352 void DownloadFileImpl::SendUpdate() { 333 void DownloadFileImpl::SendUpdate() {
353 BrowserThread::PostTask( 334 BrowserThread::PostTask(
354 BrowserThread::UI, FROM_HERE, 335 BrowserThread::UI,
336 FROM_HERE,
355 base::Bind(&DownloadDestinationObserver::DestinationUpdate, 337 base::Bind(&DownloadDestinationObserver::DestinationUpdate,
356 observer_, file_.bytes_so_far(), CurrentSpeed(), 338 observer_,
357 GetHashState())); 339 file_.bytes_so_far(),
340 rate_estimator_.GetCountPerSecond()));
358 } 341 }
359 342
360 // static 343 DownloadFileImpl::RenameParameters::RenameParameters(
361 int DownloadFile::GetNumberOfDownloadFiles() { 344 RenameOption option,
362 return number_active_objects_; 345 const base::FilePath& new_path,
363 } 346 const RenameCompletionCallback& completion_callback)
347 : option(option),
348 new_path(new_path),
349 retries_left(kMaxRenameRetries),
350 completion_callback(completion_callback) {}
351
352 DownloadFileImpl::RenameParameters::~RenameParameters() {}
364 353
365 } // namespace content 354 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/download/download_file_impl.h ('k') | content/browser/download/download_file_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698