| 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" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 if (!update_timer_->IsRunning()) { | 81 if (!update_timer_->IsRunning()) { |
| 82 update_timer_->Start(FROM_HERE, | 82 update_timer_->Start(FROM_HERE, |
| 83 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), | 83 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), |
| 84 this, &DownloadFileImpl::SendUpdate); | 84 this, &DownloadFileImpl::SendUpdate); |
| 85 } | 85 } |
| 86 return content::ConvertNetErrorToInterruptReason( | 86 return content::ConvertNetErrorToInterruptReason( |
| 87 file_.AppendDataToFile(data, data_len), | 87 file_.AppendDataToFile(data, data_len), |
| 88 content::DOWNLOAD_INTERRUPT_FROM_DISK); | 88 content::DOWNLOAD_INTERRUPT_FROM_DISK); |
| 89 } | 89 } |
| 90 | 90 |
| 91 content::DownloadInterruptReason DownloadFileImpl::Rename( | 91 void DownloadFileImpl::Rename(const FilePath& full_path, |
| 92 const FilePath& full_path) { | 92 bool overwrite_existing_file, |
| 93 return content::ConvertNetErrorToInterruptReason( | 93 const RenameCompletionCallback& callback) { |
| 94 file_.Rename(full_path), | 94 FilePath new_path(full_path); |
| 95 content::DOWNLOAD_INTERRUPT_FROM_DISK); | 95 if (!overwrite_existing_file) { |
| 96 // Make the file unique if requested. |
| 97 int uniquifier = |
| 98 file_util::GetUniquePathNumber(new_path, FILE_PATH_LITERAL("")); |
| 99 if (uniquifier > 0) { |
| 100 new_path = new_path.InsertBeforeExtensionASCII( |
| 101 StringPrintf(" (%d)", uniquifier)); |
| 102 } |
| 103 } |
| 104 |
| 105 net::Error rename_error = file_.Rename(new_path); |
| 106 content::DownloadInterruptReason reason( |
| 107 content::DOWNLOAD_INTERRUPT_REASON_NONE); |
| 108 if (net::OK != rename_error) { |
| 109 // Make sure our information is updated, since we're about to |
| 110 // error out. |
| 111 SendUpdate(); |
| 112 |
| 113 reason = |
| 114 content::ConvertNetErrorToInterruptReason( |
| 115 rename_error, |
| 116 content::DOWNLOAD_INTERRUPT_FROM_DISK); |
| 117 |
| 118 new_path.clear(); |
| 119 } |
| 120 |
| 121 BrowserThread::PostTask( |
| 122 BrowserThread::UI, FROM_HERE, |
| 123 base::Bind(callback, reason, new_path)); |
| 96 } | 124 } |
| 97 | 125 |
| 98 void DownloadFileImpl::Detach() { | 126 void DownloadFileImpl::Detach() { |
| 99 file_.Detach(); | 127 file_.Detach(); |
| 100 } | 128 } |
| 101 | 129 |
| 102 void DownloadFileImpl::Cancel() { | 130 void DownloadFileImpl::Cancel() { |
| 103 file_.Cancel(); | 131 file_.Cancel(); |
| 104 } | 132 } |
| 105 | 133 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 | 211 |
| 184 switch (state) { | 212 switch (state) { |
| 185 case content::ByteStreamReader::STREAM_EMPTY: | 213 case content::ByteStreamReader::STREAM_EMPTY: |
| 186 break; | 214 break; |
| 187 case content::ByteStreamReader::STREAM_HAS_DATA: | 215 case content::ByteStreamReader::STREAM_HAS_DATA: |
| 188 { | 216 { |
| 189 ++num_buffers; | 217 ++num_buffers; |
| 190 base::TimeTicks write_start(base::TimeTicks::Now()); | 218 base::TimeTicks write_start(base::TimeTicks::Now()); |
| 191 reason = AppendDataToFile( | 219 reason = AppendDataToFile( |
| 192 incoming_data.get()->data(), incoming_data_size); | 220 incoming_data.get()->data(), incoming_data_size); |
| 221 // Note that if we're after a rename failure but before any |
| 222 // cancel that our owner generates based on that rename failure, |
| 223 // we'll get an ERR_UNEXPECTED from the above. Our consumers |
| 224 // need to handle this situation. |
| 193 disk_writes_time_ += (base::TimeTicks::Now() - write_start); | 225 disk_writes_time_ += (base::TimeTicks::Now() - write_start); |
| 194 bytes_seen_ += incoming_data_size; | 226 bytes_seen_ += incoming_data_size; |
| 195 total_incoming_data_size += incoming_data_size; | 227 total_incoming_data_size += incoming_data_size; |
| 196 } | 228 } |
| 197 break; | 229 break; |
| 198 case content::ByteStreamReader::STREAM_COMPLETE: | 230 case content::ByteStreamReader::STREAM_COMPLETE: |
| 199 { | 231 { |
| 200 reason = stream_reader_->GetStatus(); | 232 reason = stream_reader_->GetStatus(); |
| 201 SendUpdate(); | 233 SendUpdate(); |
| 202 base::TimeTicks close_start(base::TimeTicks::Now()); | 234 base::TimeTicks close_start(base::TimeTicks::Now()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 231 | 263 |
| 232 download_stats::RecordContiguousWriteTime(now - start); | 264 download_stats::RecordContiguousWriteTime(now - start); |
| 233 | 265 |
| 234 // Take care of communication with our controller. | 266 // Take care of communication with our controller. |
| 235 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { | 267 if (reason != content::DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 236 // Error case for both upstream source and file write. | 268 // Error case for both upstream source and file write. |
| 237 // Shut down processing and signal an error to our controller. | 269 // Shut down processing and signal an error to our controller. |
| 238 // Our controller will clean us up. | 270 // Our controller will clean us up. |
| 239 stream_reader_->RegisterCallback(base::Closure()); | 271 stream_reader_->RegisterCallback(base::Closure()); |
| 240 weak_factory_.InvalidateWeakPtrs(); | 272 weak_factory_.InvalidateWeakPtrs(); |
| 273 SendUpdate(); // Make info up to date before error. |
| 241 BrowserThread::PostTask( | 274 BrowserThread::PostTask( |
| 242 BrowserThread::UI, FROM_HERE, | 275 BrowserThread::UI, FROM_HERE, |
| 243 base::Bind(&DownloadManager::OnDownloadInterrupted, | 276 base::Bind(&DownloadManager::OnDownloadInterrupted, |
| 244 download_manager_, id_.local(), | 277 download_manager_, id_.local(), reason)); |
| 245 BytesSoFar(), GetHashState(), reason)); | |
| 246 } else if (state == content::ByteStreamReader::STREAM_COMPLETE) { | 278 } else if (state == content::ByteStreamReader::STREAM_COMPLETE) { |
| 247 // Signal successful completion and shut down processing. | 279 // Signal successful completion and shut down processing. |
| 248 stream_reader_->RegisterCallback(base::Closure()); | 280 stream_reader_->RegisterCallback(base::Closure()); |
| 249 weak_factory_.InvalidateWeakPtrs(); | 281 weak_factory_.InvalidateWeakPtrs(); |
| 250 std::string hash; | 282 std::string hash; |
| 251 if (!GetHash(&hash) || file_.IsEmptyHash(hash)) | 283 if (!GetHash(&hash) || file_.IsEmptyHash(hash)) |
| 252 hash.clear(); | 284 hash.clear(); |
| 253 BrowserThread::PostTask( | 285 BrowserThread::PostTask( |
| 254 BrowserThread::UI, FROM_HERE, | 286 BrowserThread::UI, FROM_HERE, |
| 255 base::Bind(&DownloadManager::OnResponseCompleted, | 287 base::Bind(&DownloadManager::OnResponseCompleted, |
| 256 download_manager_, id_.local(), | 288 download_manager_, id_.local(), |
| 257 BytesSoFar(), hash)); | 289 BytesSoFar(), hash)); |
| 258 } | 290 } |
| 259 if (bound_net_log_.IsLoggingAllEvents()) { | 291 if (bound_net_log_.IsLoggingAllEvents()) { |
| 260 bound_net_log_.AddEvent( | 292 bound_net_log_.AddEvent( |
| 261 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED, | 293 net::NetLog::TYPE_DOWNLOAD_STREAM_DRAINED, |
| 262 base::Bind(&download_net_logs::FileStreamDrainedCallback, | 294 base::Bind(&download_net_logs::FileStreamDrainedCallback, |
| 263 total_incoming_data_size, num_buffers)); | 295 total_incoming_data_size, num_buffers)); |
| 264 } | 296 } |
| 265 } | 297 } |
| 266 | 298 |
| 267 void DownloadFileImpl::SendUpdate() { | 299 void DownloadFileImpl::SendUpdate() { |
| 268 BrowserThread::PostTask( | 300 BrowserThread::PostTask( |
| 269 BrowserThread::UI, FROM_HERE, | 301 BrowserThread::UI, FROM_HERE, |
| 270 base::Bind(&DownloadManager::UpdateDownload, | 302 base::Bind(&DownloadManager::UpdateDownload, |
| 271 download_manager_, id_.local(), | 303 download_manager_, id_.local(), |
| 272 BytesSoFar(), CurrentSpeed(), GetHashState())); | 304 BytesSoFar(), CurrentSpeed(), GetHashState())); |
| 273 } | 305 } |
| OLD | NEW |