Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(599)

Side by Side Diff: content/browser/download/download_file_manager.cc

Issue 8404049: Added member data to classes to support download resumption. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with trunk Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 26 matching lines...) Expand all
37 const int kUpdatePeriodMs = 500; 37 const int kUpdatePeriodMs = 500;
38 38
39 class DownloadFileFactoryImpl 39 class DownloadFileFactoryImpl
40 : public DownloadFileManager::DownloadFileFactory { 40 : public DownloadFileManager::DownloadFileFactory {
41 public: 41 public:
42 DownloadFileFactoryImpl() {} 42 DownloadFileFactoryImpl() {}
43 43
44 virtual content::DownloadFile* CreateFile( 44 virtual content::DownloadFile* CreateFile(
45 DownloadCreateInfo* info, 45 DownloadCreateInfo* info,
46 const DownloadRequestHandle& request_handle, 46 const DownloadRequestHandle& request_handle,
47 content::DownloadManager* download_manager) OVERRIDE; 47 content::DownloadManager* download_manager,
48 bool calculate_hash) OVERRIDE;
48 }; 49 };
49 50
50 DownloadFile* DownloadFileFactoryImpl::CreateFile( 51 DownloadFile* DownloadFileFactoryImpl::CreateFile(
51 DownloadCreateInfo* info, 52 DownloadCreateInfo* info,
52 const DownloadRequestHandle& request_handle, 53 const DownloadRequestHandle& request_handle,
53 content::DownloadManager* download_manager) { 54 content::DownloadManager* download_manager,
55 bool calculate_hash) {
54 return new DownloadFileImpl(info, 56 return new DownloadFileImpl(info,
55 new DownloadRequestHandle(request_handle), 57 new DownloadRequestHandle(request_handle),
56 download_manager); 58 download_manager, calculate_hash);
57 } 59 }
58 60
59 } // namespace 61 } // namespace
60 62
61 DownloadFileManager::DownloadFileManager(ResourceDispatcherHost* rdh, 63 DownloadFileManager::DownloadFileManager(ResourceDispatcherHost* rdh,
62 DownloadFileFactory* factory) 64 DownloadFileFactory* factory)
63 : resource_dispatcher_host_(rdh), download_file_factory_(factory) { 65 : resource_dispatcher_host_(rdh), download_file_factory_(factory) {
64 if (download_file_factory_ == NULL) 66 if (download_file_factory_ == NULL)
65 download_file_factory_.reset(new DownloadFileFactoryImpl); 67 download_file_factory_.reset(new DownloadFileFactoryImpl);
66 } 68 }
(...skipping 19 matching lines...) Expand all
86 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle, 88 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle,
87 content::DownloadManager* download_manager, bool get_hash) { 89 content::DownloadManager* download_manager, bool get_hash) {
88 DCHECK(info); 90 DCHECK(info);
89 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); 91 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString();
90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
91 93
92 // Life of |info| ends here. No more references to it after this method. 94 // Life of |info| ends here. No more references to it after this method.
93 scoped_ptr<DownloadCreateInfo> infop(info); 95 scoped_ptr<DownloadCreateInfo> infop(info);
94 96
95 scoped_ptr<DownloadFile> download_file(download_file_factory_->CreateFile( 97 scoped_ptr<DownloadFile> download_file(download_file_factory_->CreateFile(
96 info, request_handle, download_manager)); 98 info, request_handle, download_manager, get_hash));
97 if (net::OK != download_file->Initialize(get_hash)) { 99 if (net::OK != download_file->Initialize()) {
98 request_handle.CancelRequest(); 100 request_handle.CancelRequest();
99 return; 101 return;
100 } 102 }
101 103
102 DCHECK(GetDownloadFile(info->download_id) == NULL); 104 DCHECK(GetDownloadFile(info->download_id) == NULL);
103 downloads_[info->download_id] = download_file.release(); 105 downloads_[info->download_id] = download_file.release();
104 106
105 // The file is now ready, we can un-pause the request and start saving data. 107 // The file is now ready, we can un-pause the request and start saving data.
106 request_handle.ResumeRequest(); 108 request_handle.ResumeRequest();
107 109
(...skipping 27 matching lines...) Expand all
135 137
136 void DownloadFileManager::UpdateInProgressDownloads() { 138 void DownloadFileManager::UpdateInProgressDownloads() {
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
138 for (DownloadFileMap::iterator i = downloads_.begin(); 140 for (DownloadFileMap::iterator i = downloads_.begin();
139 i != downloads_.end(); ++i) { 141 i != downloads_.end(); ++i) {
140 DownloadId global_id = i->first; 142 DownloadId global_id = i->first;
141 DownloadFile* download_file = i->second; 143 DownloadFile* download_file = i->second;
142 content::DownloadManager* manager = download_file->GetDownloadManager(); 144 content::DownloadManager* manager = download_file->GetDownloadManager();
143 if (manager) { 145 if (manager) {
144 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 146 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
145 base::Bind(&content::DownloadManager::UpdateDownload, manager, 147 base::Bind(&content::DownloadManager::UpdateDownload,
146 global_id.local(), download_file->BytesSoFar(), 148 manager,
147 download_file->CurrentSpeed())); 149 global_id.local(),
150 download_file->BytesSoFar(),
151 download_file->CurrentSpeed(),
152 download_file->GetHashState()));
148 } 153 }
149 } 154 }
150 } 155 }
151 156
152 void DownloadFileManager::StartDownload( 157 void DownloadFileManager::StartDownload(
153 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { 158 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155 DCHECK(info); 160 DCHECK(info);
156 161
157 content::DownloadManager* manager = request_handle.GetDownloadManager(); 162 content::DownloadManager* manager = request_handle.GetDownloadManager();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 if (!had_error && download_file) { 195 if (!had_error && download_file) {
191 net::Error write_result = 196 net::Error write_result =
192 download_file->AppendDataToFile(data->data(), data_len); 197 download_file->AppendDataToFile(data->data(), data_len);
193 if (write_result != net::OK) { 198 if (write_result != net::OK) {
194 // Write failed: interrupt the download. 199 // Write failed: interrupt the download.
195 content::DownloadManager* download_manager = 200 content::DownloadManager* download_manager =
196 download_file->GetDownloadManager(); 201 download_file->GetDownloadManager();
197 had_error = true; 202 had_error = true;
198 203
199 int64 bytes_downloaded = download_file->BytesSoFar(); 204 int64 bytes_downloaded = download_file->BytesSoFar();
205 std::string hash_state(download_file->GetHashState());
206
200 // Calling this here in case we get more data, to avoid 207 // Calling this here in case we get more data, to avoid
201 // processing data after an error. That could lead to 208 // processing data after an error. That could lead to
202 // files that are corrupted if the later processing succeeded. 209 // files that are corrupted if the later processing succeeded.
203 CancelDownload(global_id); 210 CancelDownload(global_id);
204 download_file = NULL; // Was deleted in |CancelDownload|. 211 download_file = NULL; // Was deleted in |CancelDownload|.
205 212
206 if (download_manager) { 213 if (download_manager) {
207 BrowserThread::PostTask( 214 BrowserThread::PostTask(
208 BrowserThread::UI, FROM_HERE, 215 BrowserThread::UI, FROM_HERE,
209 base::Bind(&content::DownloadManager::OnDownloadInterrupted, 216 base::Bind(&content::DownloadManager::OnDownloadInterrupted,
210 download_manager, global_id.local(), bytes_downloaded, 217 download_manager,
218 global_id.local(),
219 bytes_downloaded,
220 hash_state,
211 ConvertNetErrorToInterruptReason( 221 ConvertNetErrorToInterruptReason(
212 write_result, DOWNLOAD_INTERRUPT_FROM_DISK))); 222 write_result,
223 DOWNLOAD_INTERRUPT_FROM_DISK)));
213 } 224 }
214 } 225 }
215 } 226 }
216 data->Release(); 227 data->Release();
217 } 228 }
218 } 229 }
219 230
220 void DownloadFileManager::OnResponseCompleted( 231 void DownloadFileManager::OnResponseCompleted(
221 DownloadId global_id, 232 DownloadId global_id,
222 InterruptReason reason, 233 InterruptReason reason,
223 const std::string& security_info) { 234 const std::string& security_info) {
224 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id 235 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id
225 << " reason = " << InterruptReasonDebugString(reason) 236 << " reason = " << InterruptReasonDebugString(reason)
226 << " security_info = \"" << security_info << "\""; 237 << " security_info = \"" << security_info << "\"";
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 238 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
228 DownloadFile* download_file = GetDownloadFile(global_id); 239 DownloadFile* download_file = GetDownloadFile(global_id);
229 if (!download_file) 240 if (!download_file)
230 return; 241 return;
231 242
232 download_file->Finish(); 243 download_file->Finish();
233 244
234 content::DownloadManager* download_manager = 245 content::DownloadManager* download_manager =
235 download_file->GetDownloadManager(); 246 download_file->GetDownloadManager();
236 if (!download_manager) { 247 if (!download_manager) {
237 CancelDownload(global_id); 248 CancelDownload(global_id);
238 return; 249 return;
239 } 250 }
240 251
241 std::string hash; 252 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) {
242 if (!download_file->GetSha256Hash(&hash) || BaseFile::IsEmptySha256Hash(hash)) 253 std::string hash;
243 hash.clear(); 254 if (!download_file->GetHash(&hash) ||
255 BaseFile::IsEmptyHash(hash)) {
256 hash.clear();
257 }
244 258
245 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) {
246 BrowserThread::PostTask( 259 BrowserThread::PostTask(
247 BrowserThread::UI, FROM_HERE, 260 BrowserThread::UI, FROM_HERE,
248 base::Bind(&content::DownloadManager::OnResponseCompleted, 261 base::Bind(&content::DownloadManager::OnResponseCompleted,
249 download_manager, global_id.local(), 262 download_manager, global_id.local(),
250 download_file->BytesSoFar(), hash)); 263 download_file->BytesSoFar(), hash));
251 } else { 264 } else {
252 BrowserThread::PostTask( 265 BrowserThread::PostTask(
253 BrowserThread::UI, FROM_HERE, 266 BrowserThread::UI, FROM_HERE,
254 base::Bind(&content::DownloadManager::OnDownloadInterrupted, 267 base::Bind(&content::DownloadManager::OnDownloadInterrupted,
255 download_manager, global_id.local(), 268 download_manager,
256 download_file->BytesSoFar(), reason)); 269 global_id.local(),
270 download_file->BytesSoFar(),
271 download_file->GetHashState(),
272 reason));
257 } 273 }
258 // We need to keep the download around until the UI thread has finalized 274 // We need to keep the download around until the UI thread has finalized
259 // the name. 275 // the name.
260 } 276 }
261 277
262 // This method will be sent via a user action, or shutdown on the UI thread, and 278 // This method will be sent via a user action, or shutdown on the UI thread, and
263 // run on the download thread. Since this message has been sent from the UI 279 // run on the download thread. Since this message has been sent from the UI
264 // thread, the download may have already completed and won't exist in our map. 280 // thread, the download may have already completed and won't exist in our map.
265 void DownloadFileManager::CancelDownload(DownloadId global_id) { 281 void DownloadFileManager::CancelDownload(DownloadId global_id) {
266 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id; 282 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 // Without a download manager, we can't cancel the request normally, so we 442 // Without a download manager, we can't cancel the request normally, so we
427 // need to do it here. The normal path will also update the download 443 // need to do it here. The normal path will also update the download
428 // history before canceling the request. 444 // history before canceling the request.
429 download_file->CancelDownloadRequest(); 445 download_file->CancelDownloadRequest();
430 return; 446 return;
431 } 447 }
432 448
433 BrowserThread::PostTask( 449 BrowserThread::PostTask(
434 BrowserThread::UI, FROM_HERE, 450 BrowserThread::UI, FROM_HERE,
435 base::Bind(&content::DownloadManager::OnDownloadInterrupted, 451 base::Bind(&content::DownloadManager::OnDownloadInterrupted,
436 download_manager, global_id.local(), 452 download_manager,
453 global_id.local(),
437 download_file->BytesSoFar(), 454 download_file->BytesSoFar(),
455 download_file->GetHashState(),
438 ConvertNetErrorToInterruptReason( 456 ConvertNetErrorToInterruptReason(
439 rename_error, DOWNLOAD_INTERRUPT_FROM_DISK))); 457 rename_error,
458 DOWNLOAD_INTERRUPT_FROM_DISK)));
440 } 459 }
441 460
442 void DownloadFileManager::EraseDownload(DownloadId global_id) { 461 void DownloadFileManager::EraseDownload(DownloadId global_id) {
443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
444 463
445 if (!ContainsKey(downloads_, global_id)) 464 if (!ContainsKey(downloads_, global_id))
446 return; 465 return;
447 466
448 DownloadFile* download_file = downloads_[global_id]; 467 DownloadFile* download_file = downloads_[global_id];
449 468
450 VLOG(20) << " " << __FUNCTION__ << "()" 469 VLOG(20) << " " << __FUNCTION__ << "()"
451 << " id = " << global_id 470 << " id = " << global_id
452 << " download_file = " << download_file->DebugString(); 471 << " download_file = " << download_file->DebugString();
453 472
454 downloads_.erase(global_id); 473 downloads_.erase(global_id);
455 474
456 delete download_file; 475 delete download_file;
457 476
458 if (downloads_.empty()) 477 if (downloads_.empty())
459 StopUpdateTimer(); 478 StopUpdateTimer();
460 } 479 }
OLDNEW
« no previous file with comments | « content/browser/download/download_file_manager.h ('k') | content/browser/download/download_file_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698