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

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

Powered by Google App Engine
This is Rietveld 408576698