| 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> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/pickle.h" |
| 13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
| 14 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 15 #include "content/browser/download/base_file.h" | 16 #include "content/browser/download/base_file.h" |
| 16 #include "content/browser/download/download_buffer.h" | 17 #include "content/browser/download/download_buffer.h" |
| 17 #include "content/browser/download/download_create_info.h" | 18 #include "content/browser/download/download_create_info.h" |
| 18 #include "content/browser/download/download_file_impl.h" | 19 #include "content/browser/download/download_file_impl.h" |
| 19 #include "content/browser/download/download_manager.h" | 20 #include "content/browser/download/download_manager.h" |
| 20 #include "content/browser/download/download_request_handle.h" | 21 #include "content/browser/download/download_request_handle.h" |
| 21 #include "content/browser/download/download_stats.h" | 22 #include "content/browser/download/download_stats.h" |
| 22 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 23 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 DCHECK(info); | 64 DCHECK(info); |
| 64 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); | 65 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); |
| 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 66 | 67 |
| 67 // Life of |info| ends here. No more references to it after this method. | 68 // Life of |info| ends here. No more references to it after this method. |
| 68 scoped_ptr<DownloadCreateInfo> infop(info); | 69 scoped_ptr<DownloadCreateInfo> infop(info); |
| 69 | 70 |
| 70 scoped_ptr<DownloadFile> download_file( | 71 scoped_ptr<DownloadFile> download_file( |
| 71 new DownloadFileImpl(info, | 72 new DownloadFileImpl(info, |
| 72 new DownloadRequestHandle(request_handle), | 73 new DownloadRequestHandle(request_handle), |
| 73 download_manager)); | 74 download_manager, |
| 75 Pickle())); |
| 74 if (net::OK != download_file->Initialize(get_hash)) { | 76 if (net::OK != download_file->Initialize(get_hash)) { |
| 75 request_handle.CancelRequest(); | 77 request_handle.CancelRequest(); |
| 76 return; | 78 return; |
| 77 } | 79 } |
| 78 | 80 |
| 79 DCHECK(GetDownloadFile(info->download_id) == NULL); | 81 DCHECK(GetDownloadFile(info->download_id) == NULL); |
| 80 downloads_[info->download_id] = download_file.release(); | 82 downloads_[info->download_id] = download_file.release(); |
| 81 | 83 |
| 82 // The file is now ready, we can un-pause the request and start saving data. | 84 // The file is now ready, we can un-pause the request and start saving data. |
| 83 request_handle.ResumeRequest(); | 85 request_handle.ResumeRequest(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 111 } | 113 } |
| 112 | 114 |
| 113 void DownloadFileManager::UpdateInProgressDownloads() { | 115 void DownloadFileManager::UpdateInProgressDownloads() { |
| 114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 115 for (DownloadFileMap::iterator i = downloads_.begin(); | 117 for (DownloadFileMap::iterator i = downloads_.begin(); |
| 116 i != downloads_.end(); ++i) { | 118 i != downloads_.end(); ++i) { |
| 117 DownloadId global_id = i->first; | 119 DownloadId global_id = i->first; |
| 118 DownloadFile* download_file = i->second; | 120 DownloadFile* download_file = i->second; |
| 119 DownloadManager* manager = download_file->GetDownloadManager(); | 121 DownloadManager* manager = download_file->GetDownloadManager(); |
| 120 if (manager) { | 122 if (manager) { |
| 123 Pickle hash_state; |
| 124 download_file->GetSha256HashState(&hash_state); |
| 125 |
| 121 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 126 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 122 base::Bind(&DownloadManager::UpdateDownload, manager, | 127 base::Bind(&DownloadManager::UpdateDownload, |
| 123 global_id.local(), download_file->BytesSoFar())); | 128 manager, |
| 129 global_id.local(), |
| 130 download_file->BytesSoFar(), |
| 131 hash_state)); |
| 124 } | 132 } |
| 125 } | 133 } |
| 126 } | 134 } |
| 127 | 135 |
| 128 void DownloadFileManager::StartDownload( | 136 void DownloadFileManager::StartDownload( |
| 129 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { | 137 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { |
| 130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 131 DCHECK(info); | 139 DCHECK(info); |
| 132 | 140 |
| 133 DownloadManager* manager = request_handle.GetDownloadManager(); | 141 DownloadManager* manager = request_handle.GetDownloadManager(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 const int data_len = (*contents)[i].second; | 176 const int data_len = (*contents)[i].second; |
| 169 if (!had_error && download_file) { | 177 if (!had_error && download_file) { |
| 170 net::Error write_result = | 178 net::Error write_result = |
| 171 download_file->AppendDataToFile(data->data(), data_len); | 179 download_file->AppendDataToFile(data->data(), data_len); |
| 172 if (write_result != net::OK) { | 180 if (write_result != net::OK) { |
| 173 // Write failed: interrupt the download. | 181 // Write failed: interrupt the download. |
| 174 DownloadManager* download_manager = download_file->GetDownloadManager(); | 182 DownloadManager* download_manager = download_file->GetDownloadManager(); |
| 175 had_error = true; | 183 had_error = true; |
| 176 | 184 |
| 177 int64 bytes_downloaded = download_file->BytesSoFar(); | 185 int64 bytes_downloaded = download_file->BytesSoFar(); |
| 186 Pickle hash_state; |
| 187 download_file->GetSha256HashState(&hash_state); |
| 188 |
| 178 // Calling this here in case we get more data, to avoid | 189 // Calling this here in case we get more data, to avoid |
| 179 // processing data after an error. That could lead to | 190 // processing data after an error. That could lead to |
| 180 // files that are corrupted if the later processing succeeded. | 191 // files that are corrupted if the later processing succeeded. |
| 181 CancelDownload(global_id); | 192 CancelDownload(global_id); |
| 182 download_file = NULL; // Was deleted in |CancelDownload|. | 193 download_file = NULL; // Was deleted in |CancelDownload|. |
| 183 | 194 |
| 184 if (download_manager) { | 195 if (download_manager) { |
| 185 BrowserThread::PostTask( | 196 BrowserThread::PostTask( |
| 186 BrowserThread::UI, FROM_HERE, | 197 BrowserThread::UI, FROM_HERE, |
| 187 base::Bind(&DownloadManager::OnDownloadInterrupted, | 198 base::Bind(&DownloadManager::OnDownloadInterrupted, |
| 188 download_manager, global_id.local(), bytes_downloaded, | 199 download_manager, |
| 200 global_id.local(), |
| 201 bytes_downloaded, |
| 202 hash_state, |
| 189 ConvertNetErrorToInterruptReason( | 203 ConvertNetErrorToInterruptReason( |
| 190 write_result, DOWNLOAD_INTERRUPT_FROM_DISK))); | 204 write_result, |
| 205 DOWNLOAD_INTERRUPT_FROM_DISK))); |
| 191 } | 206 } |
| 192 } | 207 } |
| 193 } | 208 } |
| 194 data->Release(); | 209 data->Release(); |
| 195 } | 210 } |
| 196 } | 211 } |
| 197 | 212 |
| 198 void DownloadFileManager::OnResponseCompleted( | 213 void DownloadFileManager::OnResponseCompleted( |
| 199 DownloadId global_id, | 214 DownloadId global_id, |
| 200 InterruptReason reason, | 215 InterruptReason reason, |
| 201 const std::string& security_info) { | 216 const std::string& security_info) { |
| 202 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id | 217 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id |
| 203 << " reason = " << InterruptReasonDebugString(reason) | 218 << " reason = " << InterruptReasonDebugString(reason) |
| 204 << " security_info = \"" << security_info << "\""; | 219 << " security_info = \"" << security_info << "\""; |
| 205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 206 DownloadFile* download_file = GetDownloadFile(global_id); | 221 DownloadFile* download_file = GetDownloadFile(global_id); |
| 207 if (!download_file) | 222 if (!download_file) |
| 208 return; | 223 return; |
| 209 | 224 |
| 210 download_file->Finish(); | 225 download_file->Finish(); |
| 211 | 226 |
| 212 DownloadManager* download_manager = download_file->GetDownloadManager(); | 227 DownloadManager* download_manager = download_file->GetDownloadManager(); |
| 213 if (!download_manager) { | 228 if (!download_manager) { |
| 214 CancelDownload(global_id); | 229 CancelDownload(global_id); |
| 215 return; | 230 return; |
| 216 } | 231 } |
| 217 | 232 |
| 218 std::string hash; | 233 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 219 if (!download_file->GetSha256Hash(&hash) || BaseFile::IsEmptySha256Hash(hash)) | 234 std::string hash; |
| 220 hash.clear(); | 235 if (!download_file->GetSha256Hash(&hash) || |
| 236 BaseFile::IsEmptySha256Hash(hash)) { |
| 237 hash.clear(); |
| 238 } |
| 221 | 239 |
| 222 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { | |
| 223 BrowserThread::PostTask( | 240 BrowserThread::PostTask( |
| 224 BrowserThread::UI, FROM_HERE, | 241 BrowserThread::UI, FROM_HERE, |
| 225 base::Bind(&DownloadManager::OnResponseCompleted, | 242 base::Bind(&DownloadManager::OnResponseCompleted, |
| 226 download_manager, global_id.local(), | 243 download_manager, global_id.local(), |
| 227 download_file->BytesSoFar(), hash)); | 244 download_file->BytesSoFar(), hash)); |
| 228 } else { | 245 } else { |
| 246 Pickle hash_state; |
| 247 download_file->GetSha256HashState(&hash_state); |
| 248 |
| 229 BrowserThread::PostTask( | 249 BrowserThread::PostTask( |
| 230 BrowserThread::UI, FROM_HERE, | 250 BrowserThread::UI, FROM_HERE, |
| 231 base::Bind(&DownloadManager::OnDownloadInterrupted, | 251 base::Bind(&DownloadManager::OnDownloadInterrupted, |
| 232 download_manager, global_id.local(), | 252 download_manager, |
| 233 download_file->BytesSoFar(), reason)); | 253 global_id.local(), |
| 254 download_file->BytesSoFar(), |
| 255 hash_state, |
| 256 reason)); |
| 234 } | 257 } |
| 235 // We need to keep the download around until the UI thread has finalized | 258 // We need to keep the download around until the UI thread has finalized |
| 236 // the name. | 259 // the name. |
| 237 } | 260 } |
| 238 | 261 |
| 239 // This method will be sent via a user action, or shutdown on the UI thread, and | 262 // This method will be sent via a user action, or shutdown on the UI thread, and |
| 240 // run on the download thread. Since this message has been sent from the UI | 263 // run on the download thread. Since this message has been sent from the UI |
| 241 // thread, the download may have already completed and won't exist in our map. | 264 // thread, the download may have already completed and won't exist in our map. |
| 242 void DownloadFileManager::CancelDownload(DownloadId global_id) { | 265 void DownloadFileManager::CancelDownload(DownloadId global_id) { |
| 243 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id; | 266 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 | 420 |
| 398 DownloadManager* download_manager = download_file->GetDownloadManager(); | 421 DownloadManager* download_manager = download_file->GetDownloadManager(); |
| 399 if (!download_manager) { | 422 if (!download_manager) { |
| 400 // Without a download manager, we can't cancel the request normally, so we | 423 // Without a download manager, we can't cancel the request normally, so we |
| 401 // need to do it here. The normal path will also update the download | 424 // need to do it here. The normal path will also update the download |
| 402 // history before canceling the request. | 425 // history before canceling the request. |
| 403 download_file->CancelDownloadRequest(); | 426 download_file->CancelDownloadRequest(); |
| 404 return; | 427 return; |
| 405 } | 428 } |
| 406 | 429 |
| 430 Pickle hash_state; |
| 431 download_file->GetSha256HashState(&hash_state); |
| 432 |
| 407 BrowserThread::PostTask( | 433 BrowserThread::PostTask( |
| 408 BrowserThread::UI, FROM_HERE, | 434 BrowserThread::UI, FROM_HERE, |
| 409 base::Bind(&DownloadManager::OnDownloadInterrupted, | 435 base::Bind(&DownloadManager::OnDownloadInterrupted, |
| 410 download_manager, global_id.local(), | 436 download_manager, |
| 437 global_id.local(), |
| 411 download_file->BytesSoFar(), | 438 download_file->BytesSoFar(), |
| 439 hash_state, |
| 412 ConvertNetErrorToInterruptReason( | 440 ConvertNetErrorToInterruptReason( |
| 413 rename_error, DOWNLOAD_INTERRUPT_FROM_DISK))); | 441 rename_error, |
| 442 DOWNLOAD_INTERRUPT_FROM_DISK))); |
| 414 } | 443 } |
| 415 | 444 |
| 416 void DownloadFileManager::EraseDownload(DownloadId global_id) { | 445 void DownloadFileManager::EraseDownload(DownloadId global_id) { |
| 417 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 418 | 447 |
| 419 if (!ContainsKey(downloads_, global_id)) | 448 if (!ContainsKey(downloads_, global_id)) |
| 420 return; | 449 return; |
| 421 | 450 |
| 422 DownloadFile* download_file = downloads_[global_id]; | 451 DownloadFile* download_file = downloads_[global_id]; |
| 423 | 452 |
| 424 VLOG(20) << " " << __FUNCTION__ << "()" | 453 VLOG(20) << " " << __FUNCTION__ << "()" |
| 425 << " id = " << global_id | 454 << " id = " << global_id |
| 426 << " download_file = " << download_file->DebugString(); | 455 << " download_file = " << download_file->DebugString(); |
| 427 | 456 |
| 428 downloads_.erase(global_id); | 457 downloads_.erase(global_id); |
| 429 | 458 |
| 430 delete download_file; | 459 delete download_file; |
| 431 | 460 |
| 432 if (downloads_.empty()) | 461 if (downloads_.empty()) |
| 433 StopUpdateTimer(); | 462 StopUpdateTimer(); |
| 434 } | 463 } |
| OLD | NEW |