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

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

Powered by Google App Engine
This is Rietveld 408576698