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

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

Issue 2712713007: Make DownloadFileImpl handle multiple byte streams. (Closed)
Patch Set: Work on feedback. 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
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/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
13 #include "base/time/time.h" 14 #include "base/time/time.h"
14 #include "base/values.h" 15 #include "base/values.h"
15 #include "content/browser/byte_stream.h" 16 #include "content/browser/byte_stream.h"
16 #include "content/browser/download/download_create_info.h" 17 #include "content/browser/download/download_create_info.h"
17 #include "content/browser/download/download_destination_observer.h" 18 #include "content/browser/download/download_destination_observer.h"
18 #include "content/browser/download/download_interrupt_reasons_impl.h" 19 #include "content/browser/download/download_interrupt_reasons_impl.h"
19 #include "content/browser/download/download_net_log_parameters.h" 20 #include "content/browser/download/download_net_log_parameters.h"
20 #include "content/browser/download/download_stats.h" 21 #include "content/browser/download/download_stats.h"
21 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
(...skipping 11 matching lines...) Expand all
33 const int kMaxTimeBlockingFileThreadMs = 1000; 34 const int kMaxTimeBlockingFileThreadMs = 1000;
34 35
35 // These constants control the default retry behavior for failing renames. Each 36 // These constants control the default retry behavior for failing renames. Each
36 // retry is performed after a delay that is twice the previous delay. The 37 // retry is performed after a delay that is twice the previous delay. The
37 // initial delay is specified by kInitialRenameRetryDelayMs. 38 // initial delay is specified by kInitialRenameRetryDelayMs.
38 const int kInitialRenameRetryDelayMs = 200; 39 const int kInitialRenameRetryDelayMs = 200;
39 40
40 // Number of times a failing rename is retried before giving up. 41 // Number of times a failing rename is retried before giving up.
41 const int kMaxRenameRetries = 3; 42 const int kMaxRenameRetries = 3;
42 43
44 DownloadFileImpl::SourceStream::SourceStream(int64_t offset,
45 int64_t bytes_written)
46 : offset_(offset), bytes_written_(bytes_written), finished_(false) {}
47
48 DownloadFileImpl::SourceStream::~SourceStream() = default;
49
50 void DownloadFileImpl::SourceStream::SetByteStream(
51 std::unique_ptr<ByteStreamReader> stream_reader) {
52 stream_reader_ = std::move(stream_reader);
53 }
54
55 void DownloadFileImpl::SourceStream::OnWriteBytesToDisk(int64_t bytes_write) {
56 bytes_written_ += bytes_write;
57 }
58
43 DownloadFileImpl::DownloadFileImpl( 59 DownloadFileImpl::DownloadFileImpl(
44 std::unique_ptr<DownloadSaveInfo> save_info, 60 std::unique_ptr<DownloadSaveInfo> save_info,
45 const base::FilePath& default_download_directory, 61 const base::FilePath& default_download_directory,
46 std::unique_ptr<ByteStreamReader> stream, 62 std::unique_ptr<ByteStreamReader> stream_reader,
47 const net::NetLogWithSource& download_item_net_log, 63 const net::NetLogWithSource& download_item_net_log,
64 bool is_sparse_file,
48 base::WeakPtr<DownloadDestinationObserver> observer) 65 base::WeakPtr<DownloadDestinationObserver> observer)
49 : net_log_( 66 : net_log_(
50 net::NetLogWithSource::Make(download_item_net_log.net_log(), 67 net::NetLogWithSource::Make(download_item_net_log.net_log(),
51 net::NetLogSourceType::DOWNLOAD_FILE)), 68 net::NetLogSourceType::DOWNLOAD_FILE)),
52 file_(net_log_), 69 file_(net_log_),
53 save_info_(std::move(save_info)), 70 save_info_(std::move(save_info)),
54 default_download_directory_(default_download_directory), 71 default_download_directory_(default_download_directory),
55 stream_reader_(std::move(stream)), 72 is_sparse_file_(is_sparse_file),
56 bytes_seen_(0), 73 bytes_seen_(0),
57 observer_(observer), 74 observer_(observer),
58 weak_factory_(this) { 75 weak_factory_(this) {
76 source_streams_[save_info_->offset] =
77 base::MakeUnique<SourceStream>(save_info_->offset, 0);
78 DCHECK(source_streams_.size() == static_cast<size_t>(1));
79 source_streams_.begin()->second->SetByteStream(std::move(stream_reader));
80
59 download_item_net_log.AddEvent( 81 download_item_net_log.AddEvent(
60 net::NetLogEventType::DOWNLOAD_FILE_CREATED, 82 net::NetLogEventType::DOWNLOAD_FILE_CREATED,
61 net_log_.source().ToEventParametersCallback()); 83 net_log_.source().ToEventParametersCallback());
62 net_log_.BeginEvent( 84 net_log_.BeginEvent(
63 net::NetLogEventType::DOWNLOAD_FILE_ACTIVE, 85 net::NetLogEventType::DOWNLOAD_FILE_ACTIVE,
64 download_item_net_log.source().ToEventParametersCallback()); 86 download_item_net_log.source().ToEventParametersCallback());
65 } 87 }
66 88
67 DownloadFileImpl::~DownloadFileImpl() { 89 DownloadFileImpl::~DownloadFileImpl() {
68 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 90 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
69 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ACTIVE); 91 net_log_.EndEvent(net::NetLogEventType::DOWNLOAD_FILE_ACTIVE);
70 } 92 }
71 93
72 void DownloadFileImpl::Initialize(const InitializeCallback& callback) { 94 void DownloadFileImpl::Initialize(const InitializeCallback& callback) {
73 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 95 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
74 96
75 update_timer_.reset(new base::RepeatingTimer()); 97 update_timer_.reset(new base::RepeatingTimer());
76 DownloadInterruptReason result = 98 DownloadInterruptReason result =
77 file_.Initialize(save_info_->file_path, 99 file_.Initialize(save_info_->file_path, default_download_directory_,
78 default_download_directory_, 100 std::move(save_info_->file), save_info_->offset,
79 std::move(save_info_->file),
80 save_info_->offset,
81 save_info_->hash_of_partial_file, 101 save_info_->hash_of_partial_file,
82 std::move(save_info_->hash_state), 102 std::move(save_info_->hash_state), is_sparse_file_);
83 false);
84 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) { 103 if (result != DOWNLOAD_INTERRUPT_REASON_NONE) {
85 BrowserThread::PostTask( 104 BrowserThread::PostTask(
86 BrowserThread::UI, FROM_HERE, base::Bind(callback, result)); 105 BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
87 return; 106 return;
88 } 107 }
89 108
90 stream_reader_->RegisterCallback(
91 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr()));
92
93 download_start_ = base::TimeTicks::Now(); 109 download_start_ = base::TimeTicks::Now();
94 110
95 // Primarily to make reset to zero in restart visible to owner. 111 // Primarily to make reset to zero in restart visible to owner.
96 SendUpdate(); 112 SendUpdate();
97 113
98 // Initial pull from the straw. 114 // Initial pull from the straw.
99 StreamActive(); 115 for (auto& source_stream : source_streams_)
116 RegisterAndActivateStream(source_stream.second.get());
100 117
101 BrowserThread::PostTask( 118 BrowserThread::PostTask(
102 BrowserThread::UI, FROM_HERE, base::Bind( 119 BrowserThread::UI, FROM_HERE, base::Bind(
103 callback, DOWNLOAD_INTERRUPT_REASON_NONE)); 120 callback, DOWNLOAD_INTERRUPT_REASON_NONE));
104 } 121 }
105 122
123 void DownloadFileImpl::AddByteStream(
124 std::unique_ptr<ByteStreamReader> stream_reader,
125 int64_t offset) {
126 // |source_streams_| is not thread safe, must be modified on the same thread.
127 DCHECK(thread_checker_.CalledOnValidThread());
128
129 // The |source_streams_| must have an existing entry for the stream reader.
130 auto current_source_stream = source_streams_.find(offset);
131 DCHECK(current_source_stream != source_streams_.end());
132 SourceStream* stream = current_source_stream->second.get();
133 stream->SetByteStream(std::move(stream_reader));
134
135 // Start to pull data from the stream.
136 BrowserThread::PostTask(
137 BrowserThread::FILE, FROM_HERE,
138 base::Bind(&DownloadFileImpl::RegisterAndActivateStream,
139 weak_factory_.GetWeakPtr(), stream));
140 }
141
106 DownloadInterruptReason DownloadFileImpl::AppendDataToFile( 142 DownloadInterruptReason DownloadFileImpl::AppendDataToFile(
107 const char* data, size_t data_len) { 143 const char* data, size_t data_len) {
108 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 144 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
145 WillWriteToDisk(data_len);
146 return file_.AppendDataToFile(data, data_len);
147 }
109 148
110 if (!update_timer_->IsRunning()) { 149 DownloadInterruptReason DownloadFileImpl::WriteDataToFile(int64_t offset,
111 update_timer_->Start(FROM_HERE, 150 const char* data,
112 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 151 size_t data_len) {
113 this, &DownloadFileImpl::SendUpdate); 152 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
114 } 153 WillWriteToDisk(data_len);
115 rate_estimator_.Increment(data_len); 154 return file_.WriteDataToFile(offset, data, data_len);
116 return file_.AppendDataToFile(data, data_len);
117 } 155 }
118 156
119 void DownloadFileImpl::RenameAndUniquify( 157 void DownloadFileImpl::RenameAndUniquify(
120 const base::FilePath& full_path, 158 const base::FilePath& full_path,
121 const RenameCompletionCallback& callback) { 159 const RenameCompletionCallback& callback) {
122 std::unique_ptr<RenameParameters> parameters( 160 std::unique_ptr<RenameParameters> parameters(
123 new RenameParameters(UNIQUIFY, full_path, callback)); 161 new RenameParameters(UNIQUIFY, full_path, callback));
124 RenameWithRetryInternal(std::move(parameters)); 162 RenameWithRetryInternal(std::move(parameters));
125 } 163 }
126 164
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 parameters->source_url, 244 parameters->source_url,
207 parameters->referrer_url); 245 parameters->referrer_url);
208 } 246 }
209 247
210 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { 248 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
211 // Make sure our information is updated, since we're about to 249 // Make sure our information is updated, since we're about to
212 // error out. 250 // error out.
213 SendUpdate(); 251 SendUpdate();
214 252
215 // Null out callback so that we don't do any more stream processing. 253 // Null out callback so that we don't do any more stream processing.
216 stream_reader_->RegisterCallback(base::Closure()); 254 for (auto& stream : source_streams_) {
255 ByteStreamReader* stream_reader = stream.second->stream_reader();
256 if (stream_reader)
257 stream_reader->RegisterCallback(base::Closure());
258 }
217 259
218 new_path.clear(); 260 new_path.clear();
219 } 261 }
220 262
221 BrowserThread::PostTask( 263 BrowserThread::PostTask(
222 BrowserThread::UI, 264 BrowserThread::UI,
223 FROM_HERE, 265 FROM_HERE,
224 base::Bind(parameters->completion_callback, reason, new_path)); 266 base::Bind(parameters->completion_callback, reason, new_path));
225 } 267 }
226 268
227 void DownloadFileImpl::Detach() { 269 void DownloadFileImpl::Detach() {
228 file_.Detach(); 270 file_.Detach();
229 } 271 }
230 272
231 void DownloadFileImpl::Cancel() { 273 void DownloadFileImpl::Cancel() {
232 file_.Cancel(); 274 file_.Cancel();
233 } 275 }
234 276
235 const base::FilePath& DownloadFileImpl::FullPath() const { 277 const base::FilePath& DownloadFileImpl::FullPath() const {
236 return file_.full_path(); 278 return file_.full_path();
237 } 279 }
238 280
239 bool DownloadFileImpl::InProgress() const { 281 bool DownloadFileImpl::InProgress() const {
240 return file_.in_progress(); 282 return file_.in_progress();
241 } 283 }
242 284
243 void DownloadFileImpl::StreamActive() { 285 void DownloadFileImpl::StreamActive(SourceStream* source_stream) {
286 DCHECK(source_stream->stream_reader());
244 base::TimeTicks start(base::TimeTicks::Now()); 287 base::TimeTicks start(base::TimeTicks::Now());
245 base::TimeTicks now; 288 base::TimeTicks now;
246 scoped_refptr<net::IOBuffer> incoming_data; 289 scoped_refptr<net::IOBuffer> incoming_data;
247 size_t incoming_data_size = 0; 290 size_t incoming_data_size = 0;
248 size_t total_incoming_data_size = 0; 291 size_t total_incoming_data_size = 0;
249 size_t num_buffers = 0; 292 size_t num_buffers = 0;
250 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); 293 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY);
251 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; 294 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE;
252 base::TimeDelta delta( 295 base::TimeDelta delta(
253 base::TimeDelta::FromMilliseconds(kMaxTimeBlockingFileThreadMs)); 296 base::TimeDelta::FromMilliseconds(kMaxTimeBlockingFileThreadMs));
254 297
255 // Take care of any file local activity required. 298 // Take care of any file local activity required.
256 do { 299 do {
257 state = stream_reader_->Read(&incoming_data, &incoming_data_size); 300 state = source_stream->stream_reader()->Read(&incoming_data,
301 &incoming_data_size);
258 302
259 switch (state) { 303 switch (state) {
260 case ByteStreamReader::STREAM_EMPTY: 304 case ByteStreamReader::STREAM_EMPTY:
261 break; 305 break;
262 case ByteStreamReader::STREAM_HAS_DATA: 306 case ByteStreamReader::STREAM_HAS_DATA:
263 { 307 {
264 ++num_buffers; 308 ++num_buffers;
265 base::TimeTicks write_start(base::TimeTicks::Now()); 309 base::TimeTicks write_start(base::TimeTicks::Now());
266 reason = AppendDataToFile( 310 if (is_sparse_file_) {
267 incoming_data.get()->data(), incoming_data_size); 311 reason = WriteDataToFile(
312 source_stream->offset() + source_stream->bytes_written(),
313 incoming_data.get()->data(), incoming_data_size);
314 } else {
315 reason = AppendDataToFile(incoming_data.get()->data(),
316 incoming_data_size);
317 }
268 disk_writes_time_ += (base::TimeTicks::Now() - write_start); 318 disk_writes_time_ += (base::TimeTicks::Now() - write_start);
269 bytes_seen_ += incoming_data_size; 319 bytes_seen_ += incoming_data_size;
270 total_incoming_data_size += incoming_data_size; 320 total_incoming_data_size += incoming_data_size;
321 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE)
322 source_stream->OnWriteBytesToDisk(incoming_data_size);
271 } 323 }
272 break; 324 break;
273 case ByteStreamReader::STREAM_COMPLETE: 325 case ByteStreamReader::STREAM_COMPLETE:
274 { 326 {
275 reason = static_cast<DownloadInterruptReason>( 327 reason = static_cast<DownloadInterruptReason>(
276 stream_reader_->GetStatus()); 328 source_stream->stream_reader()->GetStatus());
277 SendUpdate(); 329 SendUpdate();
278 base::TimeTicks close_start(base::TimeTicks::Now());
279 base::TimeTicks now(base::TimeTicks::Now());
280 disk_writes_time_ += (now - close_start);
281 RecordFileBandwidth(
282 bytes_seen_, disk_writes_time_, now - download_start_);
283 update_timer_.reset();
284 } 330 }
285 break; 331 break;
286 default: 332 default:
287 NOTREACHED(); 333 NOTREACHED();
288 break; 334 break;
289 } 335 }
290 now = base::TimeTicks::Now(); 336 now = base::TimeTicks::Now();
291 } while (state == ByteStreamReader::STREAM_HAS_DATA && 337 } while (state == ByteStreamReader::STREAM_HAS_DATA &&
292 reason == DOWNLOAD_INTERRUPT_REASON_NONE && 338 reason == DOWNLOAD_INTERRUPT_REASON_NONE &&
293 now - start <= delta); 339 now - start <= delta);
294 340
295 // If we're stopping to yield the thread, post a task so we come back. 341 // If we're stopping to yield the thread, post a task so we come back.
296 if (state == ByteStreamReader::STREAM_HAS_DATA && 342 if (state == ByteStreamReader::STREAM_HAS_DATA &&
297 now - start > delta) { 343 now - start > delta) {
298 BrowserThread::PostTask( 344 BrowserThread::PostTask(
299 BrowserThread::FILE, FROM_HERE, 345 BrowserThread::FILE, FROM_HERE,
300 base::Bind(&DownloadFileImpl::StreamActive, 346 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr(),
301 weak_factory_.GetWeakPtr())); 347 source_stream));
302 } 348 }
303 349
304 if (total_incoming_data_size) 350 if (total_incoming_data_size)
305 RecordFileThreadReceiveBuffers(num_buffers); 351 RecordFileThreadReceiveBuffers(num_buffers);
306 352
307 RecordContiguousWriteTime(now - start); 353 RecordContiguousWriteTime(now - start);
308 354
309 // Take care of communication with our observer. 355 // Take care of communication with our observer.
310 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { 356 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) {
357 if (state == ByteStreamReader::STREAM_COMPLETE) {
358 RecordFileBandwidth(bytes_seen_, disk_writes_time_,
359 base::TimeTicks::Now() - download_start_);
360 }
311 // Error case for both upstream source and file write. 361 // Error case for both upstream source and file write.
312 // Shut down processing and signal an error to our observer. 362 // Shut down processing and signal an error to our observer.
313 // Our observer will clean us up. 363 // Our observer will clean us up.
314 stream_reader_->RegisterCallback(base::Closure()); 364 source_stream->stream_reader()->RegisterCallback(base::Closure());
315 weak_factory_.InvalidateWeakPtrs(); 365 weak_factory_.InvalidateWeakPtrs();
316 SendUpdate(); // Make info up to date before error. 366 SendUpdate(); // Make info up to date before error.
317 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); 367 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish();
318 BrowserThread::PostTask( 368 BrowserThread::PostTask(
319 BrowserThread::UI, 369 BrowserThread::UI, FROM_HERE,
320 FROM_HERE, 370 base::Bind(&DownloadDestinationObserver::DestinationError, observer_,
321 base::Bind(&DownloadDestinationObserver::DestinationError, 371 reason, TotalBytesReceived(), base::Passed(&hash_state)));
322 observer_,
323 reason,
324 file_.bytes_so_far(),
325 base::Passed(&hash_state)));
326 } else if (state == ByteStreamReader::STREAM_COMPLETE) { 372 } else if (state == ByteStreamReader::STREAM_COMPLETE) {
327 // Signal successful completion and shut down processing. 373 // Signal successful completion of the current stream.
328 stream_reader_->RegisterCallback(base::Closure()); 374 source_stream->stream_reader()->RegisterCallback(base::Closure());
329 weak_factory_.InvalidateWeakPtrs(); 375 source_stream->set_finished(true);
376
377 // Inform observers.
330 SendUpdate(); 378 SendUpdate();
331 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish(); 379
332 BrowserThread::PostTask( 380 bool all_stream_complete = true;
333 BrowserThread::UI, 381 for (auto& stream : source_streams_) {
334 FROM_HERE, 382 if (!stream.second->is_finished()) {
335 base::Bind(&DownloadDestinationObserver::DestinationCompleted, 383 all_stream_complete = false;
336 observer_, 384 break;
337 file_.bytes_so_far(), 385 }
338 base::Passed(&hash_state))); 386 }
387
388 // All the stream reader are completed, shut down file IO processing.
389 if (all_stream_complete) {
390 RecordFileBandwidth(bytes_seen_, disk_writes_time_,
391 base::TimeTicks::Now() - download_start_);
392 weak_factory_.InvalidateWeakPtrs();
393 std::unique_ptr<crypto::SecureHash> hash_state = file_.Finish();
394 update_timer_.reset();
395 BrowserThread::PostTask(
396 BrowserThread::UI, FROM_HERE,
397 base::Bind(&DownloadDestinationObserver::DestinationCompleted,
398 observer_, TotalBytesReceived(),
399 base::Passed(&hash_state)));
400 }
339 } 401 }
340 if (net_log_.IsCapturing()) { 402 if (net_log_.IsCapturing()) {
341 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED, 403 net_log_.AddEvent(net::NetLogEventType::DOWNLOAD_STREAM_DRAINED,
342 base::Bind(&FileStreamDrainedNetLogCallback, 404 base::Bind(&FileStreamDrainedNetLogCallback,
343 total_incoming_data_size, num_buffers)); 405 total_incoming_data_size, num_buffers));
344 } 406 }
345 } 407 }
346 408
409 void DownloadFileImpl::RegisterAndActivateStream(SourceStream* source_stream) {
410 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
411 ByteStreamReader* stream_reader = source_stream->stream_reader();
412 if (stream_reader) {
413 source_stream->stream_reader()->RegisterCallback(
414 base::Bind(&DownloadFileImpl::StreamActive, weak_factory_.GetWeakPtr(),
415 source_stream));
416 StreamActive(source_stream);
417 }
418 }
419
420 int64_t DownloadFileImpl::TotalBytesReceived() const {
421 if (!is_sparse_file_)
422 return file_.bytes_so_far();
423
424 // Accumulate all valid bytes from all streams.
425 int64_t total_received = 0;
426 for (auto& stream : source_streams_)
427 total_received += stream.second->bytes_written();
428
429 return total_received;
430 }
431
347 void DownloadFileImpl::SendUpdate() { 432 void DownloadFileImpl::SendUpdate() {
433 // TODO(xingliu): Update slice info to observer to update history db.
348 BrowserThread::PostTask( 434 BrowserThread::PostTask(
349 BrowserThread::UI, 435 BrowserThread::UI, FROM_HERE,
350 FROM_HERE, 436 base::Bind(&DownloadDestinationObserver::DestinationUpdate, observer_,
351 base::Bind(&DownloadDestinationObserver::DestinationUpdate, 437 TotalBytesReceived(), rate_estimator_.GetCountPerSecond()));
352 observer_, 438 }
353 file_.bytes_so_far(), 439
354 rate_estimator_.GetCountPerSecond())); 440 void DownloadFileImpl::WillWriteToDisk(size_t data_len) {
441 if (!update_timer_->IsRunning()) {
442 update_timer_->Start(FROM_HERE,
443 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
444 this, &DownloadFileImpl::SendUpdate);
445 }
446 rate_estimator_.Increment(data_len);
355 } 447 }
356 448
357 DownloadFileImpl::RenameParameters::RenameParameters( 449 DownloadFileImpl::RenameParameters::RenameParameters(
358 RenameOption option, 450 RenameOption option,
359 const base::FilePath& new_path, 451 const base::FilePath& new_path,
360 const RenameCompletionCallback& completion_callback) 452 const RenameCompletionCallback& completion_callback)
361 : option(option), 453 : option(option),
362 new_path(new_path), 454 new_path(new_path),
363 retries_left(kMaxRenameRetries), 455 retries_left(kMaxRenameRetries),
364 completion_callback(completion_callback) {} 456 completion_callback(completion_callback) {}
365 457
366 DownloadFileImpl::RenameParameters::~RenameParameters() {} 458 DownloadFileImpl::RenameParameters::~RenameParameters() {}
367 459
368 } // namespace content 460 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698