| OLD | NEW |
| 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 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/message_loop/message_loop_proxy.h" | 11 #include "base/message_loop/message_loop_proxy.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 "content/browser/byte_stream.h" | 14 #include "content/browser/byte_stream.h" |
| 15 #include "content/browser/download/download_create_info.h" | 15 #include "content/browser/download/download_create_info.h" |
| 16 #include "content/browser/download/download_interrupt_reasons_impl.h" | 16 #include "content/browser/download/download_interrupt_reasons_impl.h" |
| 17 #include "content/browser/download/download_net_log_parameters.h" | 17 #include "content/browser/download/download_net_log_parameters.h" |
| 18 #include "content/browser/download/download_stats.h" | 18 #include "content/browser/download/download_stats.h" |
| 19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/browser/download_destination_observer.h" | 20 #include "content/public/browser/download_destination_observer.h" |
| 21 #include "content/public/browser/download_interrupt_reasons.h" |
| 21 #include "content/public/browser/power_save_blocker.h" | 22 #include "content/public/browser/power_save_blocker.h" |
| 22 #include "net/base/io_buffer.h" | 23 #include "net/base/io_buffer.h" |
| 23 | 24 |
| 24 namespace content { | 25 namespace content { |
| 25 | 26 |
| 26 const int kUpdatePeriodMs = 500; | 27 const int kUpdatePeriodMs = 500; |
| 27 const int kMaxTimeBlockingFileThreadMs = 1000; | 28 const int kMaxTimeBlockingFileThreadMs = 1000; |
| 28 | 29 |
| 29 int DownloadFile::number_active_objects_ = 0; | 30 int DownloadFile::number_active_objects_ = 0; |
| 30 | 31 |
| 31 DownloadFileImpl::DownloadFileImpl( | 32 DownloadFileImpl::DownloadFileImpl( |
| 32 scoped_ptr<DownloadSaveInfo> save_info, | 33 scoped_ptr<DownloadSaveInfo> save_info, |
| 33 const base::FilePath& default_download_directory, | 34 const base::FilePath& default_download_directory, |
| 34 const GURL& url, | 35 const GURL& url, |
| 35 const GURL& referrer_url, | 36 const GURL& referrer_url, |
| 36 bool calculate_hash, | 37 bool calculate_hash, |
| 37 scoped_ptr<ByteStreamReader> stream, | 38 scoped_ptr<ByteStreamReader<DownloadInterruptReason> > stream, |
| 38 const net::BoundNetLog& bound_net_log, | 39 const net::BoundNetLog& bound_net_log, |
| 39 scoped_ptr<PowerSaveBlocker> power_save_blocker, | 40 scoped_ptr<PowerSaveBlocker> power_save_blocker, |
| 40 base::WeakPtr<DownloadDestinationObserver> observer) | 41 base::WeakPtr<DownloadDestinationObserver> observer) |
| 41 : file_(save_info->file_path, | 42 : file_(save_info->file_path, |
| 42 url, | 43 url, |
| 43 referrer_url, | 44 referrer_url, |
| 44 save_info->offset, | 45 save_info->offset, |
| 45 calculate_hash, | 46 calculate_hash, |
| 46 save_info->hash_state, | 47 save_info->hash_state, |
| 47 save_info->file_stream.Pass(), | 48 save_info->file_stream.Pass(), |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 return file_.GetHashState(); | 201 return file_.GetHashState(); |
| 201 } | 202 } |
| 202 | 203 |
| 203 void DownloadFileImpl::StreamActive() { | 204 void DownloadFileImpl::StreamActive() { |
| 204 base::TimeTicks start(base::TimeTicks::Now()); | 205 base::TimeTicks start(base::TimeTicks::Now()); |
| 205 base::TimeTicks now; | 206 base::TimeTicks now; |
| 206 scoped_refptr<net::IOBuffer> incoming_data; | 207 scoped_refptr<net::IOBuffer> incoming_data; |
| 207 size_t incoming_data_size = 0; | 208 size_t incoming_data_size = 0; |
| 208 size_t total_incoming_data_size = 0; | 209 size_t total_incoming_data_size = 0; |
| 209 size_t num_buffers = 0; | 210 size_t num_buffers = 0; |
| 210 ByteStreamReader::StreamState state(ByteStreamReader::STREAM_EMPTY); | 211 ByteStreamReader<DownloadInterruptReason>::StreamState state( |
| 212 ByteStreamReader<DownloadInterruptReason>::STREAM_EMPTY); |
| 211 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; | 213 DownloadInterruptReason reason = DOWNLOAD_INTERRUPT_REASON_NONE; |
| 212 base::TimeDelta delta( | 214 base::TimeDelta delta( |
| 213 base::TimeDelta::FromMilliseconds(kMaxTimeBlockingFileThreadMs)); | 215 base::TimeDelta::FromMilliseconds(kMaxTimeBlockingFileThreadMs)); |
| 214 | 216 |
| 215 // Take care of any file local activity required. | 217 // Take care of any file local activity required. |
| 216 do { | 218 do { |
| 217 state = stream_reader_->Read(&incoming_data, &incoming_data_size); | 219 state = stream_reader_->Read(&incoming_data, &incoming_data_size); |
| 218 | 220 |
| 219 switch (state) { | 221 switch (state) { |
| 220 case ByteStreamReader::STREAM_EMPTY: | 222 case ByteStreamReader<DownloadInterruptReason>::STREAM_EMPTY: |
| 221 break; | 223 break; |
| 222 case ByteStreamReader::STREAM_HAS_DATA: | 224 case ByteStreamReader<DownloadInterruptReason>::STREAM_HAS_DATA: |
| 223 { | 225 { |
| 224 ++num_buffers; | 226 ++num_buffers; |
| 225 base::TimeTicks write_start(base::TimeTicks::Now()); | 227 base::TimeTicks write_start(base::TimeTicks::Now()); |
| 226 reason = AppendDataToFile( | 228 reason = AppendDataToFile( |
| 227 incoming_data.get()->data(), incoming_data_size); | 229 incoming_data.get()->data(), incoming_data_size); |
| 228 disk_writes_time_ += (base::TimeTicks::Now() - write_start); | 230 disk_writes_time_ += (base::TimeTicks::Now() - write_start); |
| 229 bytes_seen_ += incoming_data_size; | 231 bytes_seen_ += incoming_data_size; |
| 230 total_incoming_data_size += incoming_data_size; | 232 total_incoming_data_size += incoming_data_size; |
| 231 } | 233 } |
| 232 break; | 234 break; |
| 233 case ByteStreamReader::STREAM_COMPLETE: | 235 case ByteStreamReader<DownloadInterruptReason>::STREAM_COMPLETE: |
| 234 { | 236 { |
| 235 reason = stream_reader_->GetStatus(); | 237 reason = static_cast<DownloadInterruptReason>( |
| 238 stream_reader_->GetStatus()); |
| 236 SendUpdate(); | 239 SendUpdate(); |
| 237 base::TimeTicks close_start(base::TimeTicks::Now()); | 240 base::TimeTicks close_start(base::TimeTicks::Now()); |
| 238 file_.Finish(); | 241 file_.Finish(); |
| 239 base::TimeTicks now(base::TimeTicks::Now()); | 242 base::TimeTicks now(base::TimeTicks::Now()); |
| 240 disk_writes_time_ += (now - close_start); | 243 disk_writes_time_ += (now - close_start); |
| 241 RecordFileBandwidth( | 244 RecordFileBandwidth( |
| 242 bytes_seen_, disk_writes_time_, now - download_start_); | 245 bytes_seen_, disk_writes_time_, now - download_start_); |
| 243 update_timer_.reset(); | 246 update_timer_.reset(); |
| 244 } | 247 } |
| 245 break; | 248 break; |
| 246 default: | 249 default: |
| 247 NOTREACHED(); | 250 NOTREACHED(); |
| 248 break; | 251 break; |
| 249 } | 252 } |
| 250 now = base::TimeTicks::Now(); | 253 now = base::TimeTicks::Now(); |
| 251 } while (state == ByteStreamReader::STREAM_HAS_DATA && | 254 } while (state == |
| 255 ByteStreamReader<DownloadInterruptReason>::STREAM_HAS_DATA && |
| 252 reason == DOWNLOAD_INTERRUPT_REASON_NONE && | 256 reason == DOWNLOAD_INTERRUPT_REASON_NONE && |
| 253 now - start <= delta); | 257 now - start <= delta); |
| 254 | 258 |
| 255 // If we're stopping to yield the thread, post a task so we come back. | 259 // If we're stopping to yield the thread, post a task so we come back. |
| 256 if (state == ByteStreamReader::STREAM_HAS_DATA && | 260 if (state == ByteStreamReader<DownloadInterruptReason>::STREAM_HAS_DATA && |
| 257 now - start > delta) { | 261 now - start > delta) { |
| 258 BrowserThread::PostTask( | 262 BrowserThread::PostTask( |
| 259 BrowserThread::FILE, FROM_HERE, | 263 BrowserThread::FILE, FROM_HERE, |
| 260 base::Bind(&DownloadFileImpl::StreamActive, | 264 base::Bind(&DownloadFileImpl::StreamActive, |
| 261 weak_factory_.GetWeakPtr())); | 265 weak_factory_.GetWeakPtr())); |
| 262 } | 266 } |
| 263 | 267 |
| 264 if (total_incoming_data_size) | 268 if (total_incoming_data_size) |
| 265 RecordFileThreadReceiveBuffers(num_buffers); | 269 RecordFileThreadReceiveBuffers(num_buffers); |
| 266 | 270 |
| 267 RecordContiguousWriteTime(now - start); | 271 RecordContiguousWriteTime(now - start); |
| 268 | 272 |
| 269 // Take care of communication with our observer. | 273 // Take care of communication with our observer. |
| 270 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { | 274 if (reason != DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 271 // Error case for both upstream source and file write. | 275 // Error case for both upstream source and file write. |
| 272 // Shut down processing and signal an error to our observer. | 276 // Shut down processing and signal an error to our observer. |
| 273 // Our observer will clean us up. | 277 // Our observer will clean us up. |
| 274 stream_reader_->RegisterCallback(base::Closure()); | 278 stream_reader_->RegisterCallback(base::Closure()); |
| 275 weak_factory_.InvalidateWeakPtrs(); | 279 weak_factory_.InvalidateWeakPtrs(); |
| 276 SendUpdate(); // Make info up to date before error. | 280 SendUpdate(); // Make info up to date before error. |
| 277 BrowserThread::PostTask( | 281 BrowserThread::PostTask( |
| 278 BrowserThread::UI, FROM_HERE, | 282 BrowserThread::UI, FROM_HERE, |
| 279 base::Bind(&DownloadDestinationObserver::DestinationError, | 283 base::Bind(&DownloadDestinationObserver::DestinationError, |
| 280 observer_, reason)); | 284 observer_, reason)); |
| 281 } else if (state == ByteStreamReader::STREAM_COMPLETE) { | 285 } else if (state == |
| 286 ByteStreamReader<DownloadInterruptReason>::STREAM_COMPLETE) { |
| 282 // Signal successful completion and shut down processing. | 287 // Signal successful completion and shut down processing. |
| 283 stream_reader_->RegisterCallback(base::Closure()); | 288 stream_reader_->RegisterCallback(base::Closure()); |
| 284 weak_factory_.InvalidateWeakPtrs(); | 289 weak_factory_.InvalidateWeakPtrs(); |
| 285 std::string hash; | 290 std::string hash; |
| 286 if (!GetHash(&hash) || file_.IsEmptyHash(hash)) | 291 if (!GetHash(&hash) || file_.IsEmptyHash(hash)) |
| 287 hash.clear(); | 292 hash.clear(); |
| 288 SendUpdate(); | 293 SendUpdate(); |
| 289 BrowserThread::PostTask( | 294 BrowserThread::PostTask( |
| 290 BrowserThread::UI, FROM_HERE, | 295 BrowserThread::UI, FROM_HERE, |
| 291 base::Bind( | 296 base::Bind( |
| (...skipping 15 matching lines...) Expand all Loading... |
| 307 observer_, file_.bytes_so_far(), CurrentSpeed(), | 312 observer_, file_.bytes_so_far(), CurrentSpeed(), |
| 308 GetHashState())); | 313 GetHashState())); |
| 309 } | 314 } |
| 310 | 315 |
| 311 // static | 316 // static |
| 312 int DownloadFile::GetNumberOfDownloadFiles() { | 317 int DownloadFile::GetNumberOfDownloadFiles() { |
| 313 return number_active_objects_; | 318 return number_active_objects_; |
| 314 } | 319 } |
| 315 | 320 |
| 316 } // namespace content | 321 } // namespace content |
| OLD | NEW |