Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_manager.h" | 5 #include "content/browser/download/download_file_manager.h" |
| 6 | 6 |
| 7 #include <set> | |
| 8 #include <string> | |
|
Randy Smith (Not in Mondays)
2011/10/28 17:42:31
Why the extra includes?
achuithb
2011/10/28 19:37:37
To satisfy gcl lint (include what you use). We are
| |
| 9 | |
| 10 #include "base/bind.h" | |
| 7 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 8 #include "base/logging.h" | 12 #include "base/logging.h" |
| 9 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 10 #include "base/task.h" | |
| 11 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 12 #include "content/browser/browser_thread.h" | 15 #include "content/browser/browser_thread.h" |
| 13 #include "content/browser/download/download_buffer.h" | 16 #include "content/browser/download/download_buffer.h" |
| 14 #include "content/browser/download/download_create_info.h" | 17 #include "content/browser/download/download_create_info.h" |
| 15 #include "content/browser/download/download_file.h" | 18 #include "content/browser/download/download_file.h" |
| 16 #include "content/browser/download/download_manager.h" | 19 #include "content/browser/download/download_manager.h" |
| 17 #include "content/browser/download/download_request_handle.h" | 20 #include "content/browser/download/download_request_handle.h" |
| 18 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 21 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
| 19 #include "content/browser/tab_contents/tab_contents.h" | 22 #include "content/browser/tab_contents/tab_contents.h" |
| 20 #include "content/public/browser/download_manager_delegate.h" | 23 #include "content/public/browser/download_manager_delegate.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 34 } | 37 } |
| 35 | 38 |
| 36 DownloadFileManager::~DownloadFileManager() { | 39 DownloadFileManager::~DownloadFileManager() { |
| 37 DCHECK(downloads_.empty()); | 40 DCHECK(downloads_.empty()); |
| 38 } | 41 } |
| 39 | 42 |
| 40 void DownloadFileManager::Shutdown() { | 43 void DownloadFileManager::Shutdown() { |
| 41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 42 BrowserThread::PostTask( | 45 BrowserThread::PostTask( |
| 43 BrowserThread::FILE, FROM_HERE, | 46 BrowserThread::FILE, FROM_HERE, |
| 44 NewRunnableMethod(this, &DownloadFileManager::OnShutdown)); | 47 base::Bind(&DownloadFileManager::OnShutdown, this)); |
| 45 } | 48 } |
| 46 | 49 |
| 47 void DownloadFileManager::OnShutdown() { | 50 void DownloadFileManager::OnShutdown() { |
| 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 51 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 49 StopUpdateTimer(); | 52 StopUpdateTimer(); |
| 50 STLDeleteValues(&downloads_); | 53 STLDeleteValues(&downloads_); |
| 51 } | 54 } |
| 52 | 55 |
| 53 void DownloadFileManager::CreateDownloadFile( | 56 void DownloadFileManager::CreateDownloadFile( |
| 54 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle, | 57 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 71 DCHECK(GetDownloadFile(global_id) == NULL); | 74 DCHECK(GetDownloadFile(global_id) == NULL); |
| 72 downloads_[global_id] = download_file.release(); | 75 downloads_[global_id] = download_file.release(); |
| 73 | 76 |
| 74 // The file is now ready, we can un-pause the request and start saving data. | 77 // The file is now ready, we can un-pause the request and start saving data. |
| 75 request_handle.ResumeRequest(); | 78 request_handle.ResumeRequest(); |
| 76 | 79 |
| 77 StartUpdateTimer(); | 80 StartUpdateTimer(); |
| 78 | 81 |
| 79 BrowserThread::PostTask( | 82 BrowserThread::PostTask( |
| 80 BrowserThread::UI, FROM_HERE, | 83 BrowserThread::UI, FROM_HERE, |
| 81 NewRunnableMethod(download_manager, | 84 base::Bind(&DownloadManager::StartDownload, download_manager, |
| 82 &DownloadManager::StartDownload, info->download_id)); | 85 info->download_id)); |
| 83 } | 86 } |
| 84 | 87 |
| 85 DownloadFile* DownloadFileManager::GetDownloadFile(DownloadId global_id) { | 88 DownloadFile* DownloadFileManager::GetDownloadFile(DownloadId global_id) { |
| 86 DownloadFileMap::iterator it = downloads_.find(global_id); | 89 DownloadFileMap::iterator it = downloads_.find(global_id); |
| 87 return it == downloads_.end() ? NULL : it->second; | 90 return it == downloads_.end() ? NULL : it->second; |
| 88 } | 91 } |
| 89 | 92 |
| 90 void DownloadFileManager::StartUpdateTimer() { | 93 void DownloadFileManager::StartUpdateTimer() { |
| 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 92 if (!update_timer_.IsRunning()) { | 95 if (!update_timer_.IsRunning()) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 103 | 106 |
| 104 void DownloadFileManager::UpdateInProgressDownloads() { | 107 void DownloadFileManager::UpdateInProgressDownloads() { |
| 105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 106 for (DownloadFileMap::iterator i = downloads_.begin(); | 109 for (DownloadFileMap::iterator i = downloads_.begin(); |
| 107 i != downloads_.end(); ++i) { | 110 i != downloads_.end(); ++i) { |
| 108 DownloadId global_id = i->first; | 111 DownloadId global_id = i->first; |
| 109 DownloadFile* download_file = i->second; | 112 DownloadFile* download_file = i->second; |
| 110 DownloadManager* manager = download_file->GetDownloadManager(); | 113 DownloadManager* manager = download_file->GetDownloadManager(); |
| 111 if (manager) { | 114 if (manager) { |
| 112 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 115 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 113 NewRunnableMethod(manager, &DownloadManager::UpdateDownload, | 116 base::Bind(&DownloadManager::UpdateDownload, manager, |
| 114 global_id.local(), download_file->bytes_so_far())); | 117 global_id.local(), download_file->bytes_so_far())); |
| 115 } | 118 } |
| 116 } | 119 } |
| 117 } | 120 } |
| 118 | 121 |
| 119 void DownloadFileManager::StartDownload( | 122 void DownloadFileManager::StartDownload( |
| 120 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { | 123 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { |
| 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 122 DCHECK(info); | 125 DCHECK(info); |
| 123 | 126 |
| 124 DownloadManager* manager = request_handle.GetDownloadManager(); | 127 DownloadManager* manager = request_handle.GetDownloadManager(); |
| 125 if (!manager) { | 128 if (!manager) { |
| 126 request_handle.CancelRequest(); | 129 request_handle.CancelRequest(); |
| 127 delete info; | 130 delete info; |
| 128 return; | 131 return; |
| 129 } | 132 } |
| 130 | 133 |
| 131 // TODO(phajdan.jr): fix the duplication of path info below. | 134 // TODO(phajdan.jr): fix the duplication of path info below. |
| 132 info->path = info->save_info.file_path; | 135 info->path = info->save_info.file_path; |
| 133 | 136 |
| 134 manager->CreateDownloadItem(info, request_handle); | 137 manager->CreateDownloadItem(info, request_handle); |
| 135 bool hash_needed = manager->delegate()->GenerateFileHash(); | 138 bool hash_needed = manager->delegate()->GenerateFileHash(); |
| 136 | 139 |
| 137 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 140 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 138 NewRunnableMethod(this, &DownloadFileManager::CreateDownloadFile, | 141 base::Bind(&DownloadFileManager::CreateDownloadFile, this, |
| 139 info, request_handle, make_scoped_refptr(manager), | 142 info, request_handle, make_scoped_refptr(manager), |
| 140 hash_needed)); | 143 hash_needed)); |
| 141 } | 144 } |
| 142 | 145 |
| 143 // We don't forward an update to the UI thread here, since we want to throttle | 146 // We don't forward an update to the UI thread here, since we want to throttle |
| 144 // the UI update rate via a periodic timer. If the user has cancelled the | 147 // the UI update rate via a periodic timer. If the user has cancelled the |
| 145 // download (in the UI thread), we may receive a few more updates before the IO | 148 // download (in the UI thread), we may receive a few more updates before the IO |
| 146 // thread gets the cancel message: we just delete the data since the | 149 // thread gets the cancel message: we just delete the data since the |
| 147 // DownloadFile has been deleted. | 150 // DownloadFile has been deleted. |
| 148 void DownloadFileManager::UpdateDownload( | 151 void DownloadFileManager::UpdateDownload( |
| 149 DownloadId global_id, content::DownloadBuffer* buffer) { | 152 DownloadId global_id, content::DownloadBuffer* buffer) { |
| 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 153 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 165 | 168 |
| 166 int64 bytes_downloaded = download_file->bytes_so_far(); | 169 int64 bytes_downloaded = download_file->bytes_so_far(); |
| 167 // Calling this here in case we get more data, to avoid | 170 // Calling this here in case we get more data, to avoid |
| 168 // processing data after an error. That could lead to | 171 // processing data after an error. That could lead to |
| 169 // files that are corrupted if the later processing succeeded. | 172 // files that are corrupted if the later processing succeeded. |
| 170 CancelDownload(global_id); | 173 CancelDownload(global_id); |
| 171 download_file = NULL; // Was deleted in |CancelDownload|. | 174 download_file = NULL; // Was deleted in |CancelDownload|. |
| 172 | 175 |
| 173 if (download_manager) { | 176 if (download_manager) { |
| 174 BrowserThread::PostTask( | 177 BrowserThread::PostTask( |
| 175 BrowserThread::UI, | 178 BrowserThread::UI, FROM_HERE, |
| 176 FROM_HERE, | 179 base::Bind(&DownloadManager::OnDownloadInterrupted, |
| 177 NewRunnableMethod( | 180 download_manager, global_id.local(), bytes_downloaded, |
| 178 download_manager, | 181 ConvertNetErrorToInterruptReason( |
| 179 &DownloadManager::OnDownloadInterrupted, | 182 write_result, DOWNLOAD_INTERRUPT_FROM_DISK))); |
| 180 global_id.local(), | |
| 181 bytes_downloaded, | |
| 182 ConvertNetErrorToInterruptReason( | |
| 183 write_result, | |
| 184 DOWNLOAD_INTERRUPT_FROM_DISK))); | |
| 185 } | 183 } |
| 186 } | 184 } |
| 187 } | 185 } |
| 188 data->Release(); | 186 data->Release(); |
| 189 } | 187 } |
| 190 } | 188 } |
| 191 | 189 |
| 192 void DownloadFileManager::OnResponseCompleted( | 190 void DownloadFileManager::OnResponseCompleted( |
| 193 DownloadId global_id, | 191 DownloadId global_id, |
| 194 InterruptReason reason, | 192 InterruptReason reason, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 208 CancelDownload(global_id); | 206 CancelDownload(global_id); |
| 209 return; | 207 return; |
| 210 } | 208 } |
| 211 | 209 |
| 212 std::string hash; | 210 std::string hash; |
| 213 if (!download_file->GetSha256Hash(&hash)) | 211 if (!download_file->GetSha256Hash(&hash)) |
| 214 hash.clear(); | 212 hash.clear(); |
| 215 | 213 |
| 216 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { | 214 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 217 BrowserThread::PostTask( | 215 BrowserThread::PostTask( |
| 218 BrowserThread::UI, | 216 BrowserThread::UI, FROM_HERE, |
| 219 FROM_HERE, | 217 base::Bind(&DownloadManager::OnResponseCompleted, |
| 220 NewRunnableMethod( | 218 download_manager, global_id.local(), |
| 221 download_manager, | 219 download_file->bytes_so_far(), hash)); |
| 222 &DownloadManager::OnResponseCompleted, | |
| 223 global_id.local(), | |
| 224 download_file->bytes_so_far(), | |
| 225 hash)); | |
| 226 } else { | 220 } else { |
| 227 BrowserThread::PostTask( | 221 BrowserThread::PostTask( |
| 228 BrowserThread::UI, | 222 BrowserThread::UI, FROM_HERE, |
| 229 FROM_HERE, | 223 base::Bind(&DownloadManager::OnDownloadInterrupted, |
| 230 NewRunnableMethod( | 224 download_manager, global_id.local(), |
| 231 download_manager, | 225 download_file->bytes_so_far(), reason)); |
| 232 &DownloadManager::OnDownloadInterrupted, | |
| 233 global_id.local(), | |
| 234 download_file->bytes_so_far(), | |
| 235 reason)); | |
| 236 } | 226 } |
| 237 // We need to keep the download around until the UI thread has finalized | 227 // We need to keep the download around until the UI thread has finalized |
| 238 // the name. | 228 // the name. |
| 239 } | 229 } |
| 240 | 230 |
| 241 // This method will be sent via a user action, or shutdown on the UI thread, and | 231 // This method will be sent via a user action, or shutdown on the UI thread, and |
| 242 // run on the download thread. Since this message has been sent from the UI | 232 // run on the download thread. Since this message has been sent from the UI |
| 243 // thread, the download may have already completed and won't exist in our map. | 233 // thread, the download may have already completed and won't exist in our map. |
| 244 void DownloadFileManager::CancelDownload(DownloadId global_id) { | 234 void DownloadFileManager::CancelDownload(DownloadId global_id) { |
| 245 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id; | 235 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 376 } | 366 } |
| 377 | 367 |
| 378 #if defined(OS_MACOSX) | 368 #if defined(OS_MACOSX) |
| 379 // Done here because we only want to do this once; see | 369 // Done here because we only want to do this once; see |
| 380 // http://crbug.com/13120 for details. | 370 // http://crbug.com/13120 for details. |
| 381 download_file->AnnotateWithSourceInformation(); | 371 download_file->AnnotateWithSourceInformation(); |
| 382 #endif | 372 #endif |
| 383 | 373 |
| 384 BrowserThread::PostTask( | 374 BrowserThread::PostTask( |
| 385 BrowserThread::UI, FROM_HERE, | 375 BrowserThread::UI, FROM_HERE, |
| 386 NewRunnableMethod( | 376 base::Bind(&DownloadManager::OnDownloadRenamedToFinalName, |
| 387 download_manager, &DownloadManager::OnDownloadRenamedToFinalName, | 377 download_manager, global_id.local(), new_path, uniquifier)); |
| 388 global_id.local(), new_path, uniquifier)); | |
| 389 } | 378 } |
| 390 | 379 |
| 391 // Called only from RenameInProgressDownloadFile and | 380 // Called only from RenameInProgressDownloadFile and |
| 392 // RenameCompletingDownloadFile on the FILE thread. | 381 // RenameCompletingDownloadFile on the FILE thread. |
| 393 void DownloadFileManager::CancelDownloadOnRename( | 382 void DownloadFileManager::CancelDownloadOnRename( |
| 394 DownloadId global_id, net::Error rename_error) { | 383 DownloadId global_id, net::Error rename_error) { |
| 395 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 396 | 385 |
| 397 DownloadFile* download_file = GetDownloadFile(global_id); | 386 DownloadFile* download_file = GetDownloadFile(global_id); |
| 398 if (!download_file) | 387 if (!download_file) |
| 399 return; | 388 return; |
| 400 | 389 |
| 401 DownloadManager* download_manager = download_file->GetDownloadManager(); | 390 DownloadManager* download_manager = download_file->GetDownloadManager(); |
| 402 if (!download_manager) { | 391 if (!download_manager) { |
| 403 // Without a download manager, we can't cancel the request normally, so we | 392 // Without a download manager, we can't cancel the request normally, so we |
| 404 // need to do it here. The normal path will also update the download | 393 // need to do it here. The normal path will also update the download |
| 405 // history before canceling the request. | 394 // history before canceling the request. |
| 406 download_file->CancelDownloadRequest(); | 395 download_file->CancelDownloadRequest(); |
| 407 return; | 396 return; |
| 408 } | 397 } |
| 409 | 398 |
| 410 BrowserThread::PostTask( | 399 BrowserThread::PostTask( |
| 411 BrowserThread::UI, FROM_HERE, | 400 BrowserThread::UI, FROM_HERE, |
| 412 NewRunnableMethod(download_manager, | 401 base::Bind(&DownloadManager::OnDownloadInterrupted, |
| 413 &DownloadManager::OnDownloadInterrupted, | 402 download_manager, global_id.local(), |
| 414 global_id.local(), | 403 download_file->bytes_so_far(), |
| 415 download_file->bytes_so_far(), | 404 ConvertNetErrorToInterruptReason( |
| 416 ConvertNetErrorToInterruptReason( | 405 rename_error, DOWNLOAD_INTERRUPT_FROM_DISK))); |
| 417 rename_error, | |
| 418 DOWNLOAD_INTERRUPT_FROM_DISK))); | |
| 419 } | 406 } |
| 420 | 407 |
| 421 void DownloadFileManager::EraseDownload(DownloadId global_id) { | 408 void DownloadFileManager::EraseDownload(DownloadId global_id) { |
| 422 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 409 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 423 | 410 |
| 424 if (!ContainsKey(downloads_, global_id)) | 411 if (!ContainsKey(downloads_, global_id)) |
| 425 return; | 412 return; |
| 426 | 413 |
| 427 DownloadFile* download_file = downloads_[global_id]; | 414 DownloadFile* download_file = downloads_[global_id]; |
| 428 | 415 |
| 429 VLOG(20) << " " << __FUNCTION__ << "()" | 416 VLOG(20) << " " << __FUNCTION__ << "()" |
| 430 << " id = " << global_id | 417 << " id = " << global_id |
| 431 << " download_file = " << download_file->DebugString(); | 418 << " download_file = " << download_file->DebugString(); |
| 432 | 419 |
| 433 downloads_.erase(global_id); | 420 downloads_.erase(global_id); |
| 434 | 421 |
| 435 delete download_file; | 422 delete download_file; |
| 436 | 423 |
| 437 if (downloads_.empty()) | 424 if (downloads_.empty()) |
| 438 StopUpdateTimer(); | 425 StopUpdateTimer(); |
| 439 } | 426 } |
| OLD | NEW |