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

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, 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"
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698