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

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

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