| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/download/download_file_manager.h" | 5 #include "chrome/browser/download/download_file_manager.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/task.h" | 8 #include "base/task.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 resource_dispatcher_host_, | 195 resource_dispatcher_host_, |
| 196 info->child_id, | 196 info->child_id, |
| 197 info->request_id)); | 197 info->request_id)); |
| 198 delete info; | 198 delete info; |
| 199 delete download; | 199 delete download; |
| 200 return; | 200 return; |
| 201 } | 201 } |
| 202 | 202 |
| 203 DCHECK(GetDownloadFile(info->download_id) == NULL); | 203 DCHECK(GetDownloadFile(info->download_id) == NULL); |
| 204 downloads_[info->download_id] = download; | 204 downloads_[info->download_id] = download; |
| 205 info->path = download->full_path(); | 205 // TODO(phajdan.jr): fix the duplication of path info below. |
| 206 info->path = info->save_info.file_path; |
| 206 { | 207 { |
| 207 AutoLock lock(progress_lock_); | 208 AutoLock lock(progress_lock_); |
| 208 ui_progress_[info->download_id] = info->received_bytes; | 209 ui_progress_[info->download_id] = info->received_bytes; |
| 209 } | 210 } |
| 210 | 211 |
| 211 ChromeThread::PostTask( | 212 ChromeThread::PostTask( |
| 212 ChromeThread::UI, FROM_HERE, | 213 ChromeThread::UI, FROM_HERE, |
| 213 NewRunnableMethod(this, &DownloadFileManager::OnStartDownload, info)); | 214 NewRunnableMethod(this, &DownloadFileManager::OnStartDownload, info)); |
| 214 } | 215 } |
| 215 | 216 |
| 216 // We don't forward an update to the UI thread here, since we want to throttle | 217 // We don't forward an update to the UI thread here, since we want to throttle |
| 217 // the UI update rate via a periodic timer. If the user has cancelled the | 218 // the UI update rate via a periodic timer. If the user has cancelled the |
| 218 // download (in the UI thread), we may receive a few more updates before the IO | 219 // download (in the UI thread), we may receive a few more updates before the IO |
| 219 // thread gets the cancel message: we just delete the data since the | 220 // thread gets the cancel message: we just delete the data since the |
| 220 // DownloadFile has been deleted. | 221 // DownloadFile has been deleted. |
| 221 void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { | 222 void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) { |
| 222 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); | 223 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 223 std::vector<DownloadBuffer::Contents> contents; | 224 std::vector<DownloadBuffer::Contents> contents; |
| 224 { | 225 { |
| 225 AutoLock auto_lock(buffer->lock); | 226 AutoLock auto_lock(buffer->lock); |
| 226 contents.swap(buffer->contents); | 227 contents.swap(buffer->contents); |
| 227 } | 228 } |
| 228 | 229 |
| 230 // Keep track of how many bytes we have successfully saved to update |
| 231 // our progress status in the UI. |
| 232 int64 progress_bytes = 0; |
| 233 |
| 229 DownloadFile* download = GetDownloadFile(id); | 234 DownloadFile* download = GetDownloadFile(id); |
| 230 for (size_t i = 0; i < contents.size(); ++i) { | 235 for (size_t i = 0; i < contents.size(); ++i) { |
| 231 net::IOBuffer* data = contents[i].first; | 236 net::IOBuffer* data = contents[i].first; |
| 232 const int data_len = contents[i].second; | 237 const int data_len = contents[i].second; |
| 233 if (download) | 238 if (download) { |
| 234 download->AppendDataToFile(data->data(), data_len); | 239 if (download->AppendDataToFile(data->data(), data_len)) |
| 240 progress_bytes += data_len; |
| 241 } |
| 235 data->Release(); | 242 data->Release(); |
| 236 } | 243 } |
| 237 | 244 |
| 238 if (download) { | 245 if (download) { |
| 239 AutoLock lock(progress_lock_); | 246 AutoLock lock(progress_lock_); |
| 240 ui_progress_[download->id()] = download->bytes_so_far(); | 247 ui_progress_[download->id()] += progress_bytes; |
| 241 } | 248 } |
| 242 } | 249 } |
| 243 | 250 |
| 244 void DownloadFileManager::DownloadFinished(int id, DownloadBuffer* buffer) { | 251 void DownloadFileManager::DownloadFinished(int id, DownloadBuffer* buffer) { |
| 245 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); | 252 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 246 delete buffer; | 253 delete buffer; |
| 247 DownloadFileMap::iterator it = downloads_.find(id); | 254 DownloadFileMap::iterator it = downloads_.find(id); |
| 248 if (it != downloads_.end()) { | 255 if (it != downloads_.end()) { |
| 249 DownloadFile* download = it->second; | 256 DownloadFile* download = it->second; |
| 250 download->set_in_progress(false); | 257 download->Finish(); |
| 258 |
| 259 int64 download_size = -1; |
| 260 { |
| 261 AutoLock lock(progress_lock_); |
| 262 download_size = ui_progress_[download->id()]; |
| 263 } |
| 251 | 264 |
| 252 ChromeThread::PostTask( | 265 ChromeThread::PostTask( |
| 253 ChromeThread::UI, FROM_HERE, | 266 ChromeThread::UI, FROM_HERE, |
| 254 NewRunnableMethod( | 267 NewRunnableMethod( |
| 255 this, &DownloadFileManager::OnDownloadFinished, | 268 this, &DownloadFileManager::OnDownloadFinished, |
| 256 id, download->bytes_so_far())); | 269 id, download_size)); |
| 257 | 270 |
| 258 // We need to keep the download around until the UI thread has finalized | 271 // We need to keep the download around until the UI thread has finalized |
| 259 // the name. | 272 // the name. |
| 260 if (download->path_renamed()) { | 273 if (download->path_renamed()) { |
| 261 downloads_.erase(it); | 274 downloads_.erase(it); |
| 262 delete download; | 275 delete download; |
| 263 } | 276 } |
| 264 } | 277 } |
| 265 | 278 |
| 266 if (downloads_.empty()) | 279 if (downloads_.empty()) |
| 267 ChromeThread::PostTask( | 280 ChromeThread::PostTask( |
| 268 ChromeThread::UI, FROM_HERE, | 281 ChromeThread::UI, FROM_HERE, |
| 269 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer)); | 282 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer)); |
| 270 } | 283 } |
| 271 | 284 |
| 272 // This method will be sent via a user action, or shutdown on the UI thread, and | 285 // This method will be sent via a user action, or shutdown on the UI thread, and |
| 273 // run on the download thread. Since this message has been sent from the UI | 286 // run on the download thread. Since this message has been sent from the UI |
| 274 // thread, the download may have already completed and won't exist in our map. | 287 // thread, the download may have already completed and won't exist in our map. |
| 275 void DownloadFileManager::CancelDownload(int id) { | 288 void DownloadFileManager::CancelDownload(int id) { |
| 276 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); | 289 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); |
| 277 DownloadFileMap::iterator it = downloads_.find(id); | 290 DownloadFileMap::iterator it = downloads_.find(id); |
| 278 if (it != downloads_.end()) { | 291 if (it != downloads_.end()) { |
| 279 DownloadFile* download = it->second; | 292 DownloadFile* download = it->second; |
| 280 download->set_in_progress(false); | |
| 281 | |
| 282 download->Cancel(); | 293 download->Cancel(); |
| 283 | 294 |
| 284 ChromeThread::PostTask( | 295 ChromeThread::PostTask( |
| 285 ChromeThread::UI, FROM_HERE, | 296 ChromeThread::UI, FROM_HERE, |
| 286 NewRunnableMethod( | 297 NewRunnableMethod( |
| 287 this, &DownloadFileManager::RemoveDownloadFromUIProgress, | 298 this, &DownloadFileManager::RemoveDownloadFromUIProgress, |
| 288 download->id())); | 299 download->id())); |
| 289 | 300 |
| 290 if (download->path_renamed()) { | 301 if (download->path_renamed()) { |
| 291 downloads_.erase(it); | 302 downloads_.erase(it); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 } else { | 441 } else { |
| 431 // Error. Between the time the UI thread generated 'full_path' to the time | 442 // Error. Between the time the UI thread generated 'full_path' to the time |
| 432 // this code runs, something happened that prevents us from renaming. | 443 // this code runs, something happened that prevents us from renaming. |
| 433 DownloadManagerMap::iterator dmit = managers_.find(download->id()); | 444 DownloadManagerMap::iterator dmit = managers_.find(download->id()); |
| 434 if (dmit != managers_.end()) { | 445 if (dmit != managers_.end()) { |
| 435 DownloadManager* dlm = dmit->second; | 446 DownloadManager* dlm = dmit->second; |
| 436 ChromeThread::PostTask( | 447 ChromeThread::PostTask( |
| 437 ChromeThread::UI, FROM_HERE, | 448 ChromeThread::UI, FROM_HERE, |
| 438 NewRunnableMethod(dlm, &DownloadManager::DownloadCancelled, id)); | 449 NewRunnableMethod(dlm, &DownloadManager::DownloadCancelled, id)); |
| 439 } else { | 450 } else { |
| 440 ChromeThread::PostTask( | 451 download->CancelDownloadRequest(resource_dispatcher_host_); |
| 441 ChromeThread::IO, FROM_HERE, | |
| 442 NewRunnableFunction(&download_util::CancelDownloadRequest, | |
| 443 resource_dispatcher_host_, | |
| 444 download->child_id(), | |
| 445 download->request_id())); | |
| 446 } | 452 } |
| 447 } | 453 } |
| 448 | 454 |
| 449 // If the download has completed before we got this final name, we remove it | 455 // If the download has completed before we got this final name, we remove it |
| 450 // from our in progress map. | 456 // from our in progress map. |
| 451 if (!download->in_progress()) { | 457 if (!download->in_progress()) { |
| 452 downloads_.erase(it); | 458 downloads_.erase(it); |
| 453 delete download; | 459 delete download; |
| 454 } | 460 } |
| 455 | 461 |
| 456 if (downloads_.empty()) { | 462 if (downloads_.empty()) { |
| 457 ChromeThread::PostTask( | 463 ChromeThread::PostTask( |
| 458 ChromeThread::UI, FROM_HERE, | 464 ChromeThread::UI, FROM_HERE, |
| 459 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer)); | 465 NewRunnableMethod(this, &DownloadFileManager::StopUpdateTimer)); |
| 460 } | 466 } |
| 461 } | 467 } |
| 462 | 468 |
| OLD | NEW |