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 |