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

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

Issue 8372034: Created an interface for DownloadFile, for use in unit tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleaned up download file interface and unit test class. 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/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "content/browser/download/download_buffer.h" 15 #include "content/browser/download/download_buffer.h"
16 #include "content/browser/download/download_create_info.h" 16 #include "content/browser/download/download_create_info.h"
17 #include "content/browser/download/download_file.h" 17 #include "content/browser/download/download_file_impl.h"
18 #include "content/browser/download/download_manager.h" 18 #include "content/browser/download/download_manager.h"
19 #include "content/browser/download/download_request_handle.h" 19 #include "content/browser/download/download_request_handle.h"
20 #include "content/browser/download/download_stats.h" 20 #include "content/browser/download/download_stats.h"
21 #include "content/browser/renderer_host/resource_dispatcher_host.h" 21 #include "content/browser/renderer_host/resource_dispatcher_host.h"
22 #include "content/browser/tab_contents/tab_contents.h" 22 #include "content/browser/tab_contents/tab_contents.h"
23 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/download_manager_delegate.h" 24 #include "content/public/browser/download_manager_delegate.h"
25 #include "googleurl/src/gurl.h" 25 #include "googleurl/src/gurl.h"
26 #include "net/base/io_buffer.h" 26 #include "net/base/io_buffer.h"
27 27
(...skipping 21 matching lines...) Expand all
49 BrowserThread::FILE, FROM_HERE, 49 BrowserThread::FILE, FROM_HERE,
50 base::Bind(&DownloadFileManager::OnShutdown, this)); 50 base::Bind(&DownloadFileManager::OnShutdown, this));
51 } 51 }
52 52
53 void DownloadFileManager::OnShutdown() { 53 void DownloadFileManager::OnShutdown() {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
55 StopUpdateTimer(); 55 StopUpdateTimer();
56 STLDeleteValues(&downloads_); 56 STLDeleteValues(&downloads_);
57 } 57 }
58 58
59 DownloadFile* DownloadFileManager::NewDownloadFile(
60 DownloadCreateInfo* info,
61 const DownloadRequestHandle& request_handle,
62 DownloadManager* download_manager) {
63 return new DownloadFileImpl(info,
64 new DownloadRequestHandle(request_handle),
65 download_manager);
66 }
67
59 void DownloadFileManager::CreateDownloadFile( 68 void DownloadFileManager::CreateDownloadFile(
60 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle, 69 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle,
61 DownloadManager* download_manager, bool get_hash) { 70 DownloadManager* download_manager, bool get_hash) {
62 DCHECK(info); 71 DCHECK(info);
63 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString(); 72 VLOG(20) << __FUNCTION__ << "()" << " info = " << info->DebugString();
64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 73 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
65 74
66 // Life of |info| ends here. No more references to it after this method. 75 // Life of |info| ends here. No more references to it after this method.
67 scoped_ptr<DownloadCreateInfo> infop(info); 76 scoped_ptr<DownloadCreateInfo> infop(info);
68 77
69 scoped_ptr<DownloadFile> 78 scoped_ptr<DownloadFile> download_file(
70 download_file(new DownloadFile(info, 79 NewDownloadFile(info, request_handle, download_manager));
71 new DownloadRequestHandle(request_handle),
72 download_manager));
73 if (net::OK != download_file->Initialize(get_hash)) { 80 if (net::OK != download_file->Initialize(get_hash)) {
74 request_handle.CancelRequest(); 81 request_handle.CancelRequest();
75 return; 82 return;
76 } 83 }
77 84
78 DCHECK(GetDownloadFile(info->download_id) == NULL); 85 DCHECK(GetDownloadFile(info->download_id) == NULL);
79 downloads_[info->download_id] = download_file.release(); 86 downloads_[info->download_id] = download_file.release();
80 87
81 // The file is now ready, we can un-pause the request and start saving data. 88 // The file is now ready, we can un-pause the request and start saving data.
82 request_handle.ResumeRequest(); 89 request_handle.ResumeRequest();
83 90
84 StartUpdateTimer(); 91 StartUpdateTimer();
85 92
86 BrowserThread::PostTask( 93 BrowserThread::PostTask(
87 BrowserThread::UI, FROM_HERE, 94 BrowserThread::UI, FROM_HERE,
88 base::Bind(&DownloadManager::StartDownload, download_manager, 95 base::Bind(&DownloadManager::StartDownload, download_manager,
89 info->download_id.local())); 96 info->download_id.local()));
90 } 97 }
91 98
92 DownloadFile* DownloadFileManager::GetDownloadFile(DownloadId global_id) { 99 DownloadFile* DownloadFileManager::GetDownloadFile(
100 DownloadId global_id) {
93 DownloadFileMap::iterator it = downloads_.find(global_id); 101 DownloadFileMap::iterator it = downloads_.find(global_id);
94 return it == downloads_.end() ? NULL : it->second; 102 return it == downloads_.end() ? NULL : it->second;
95 } 103 }
96 104
97 void DownloadFileManager::StartUpdateTimer() { 105 void DownloadFileManager::StartUpdateTimer() {
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
99 if (!update_timer_.IsRunning()) { 107 if (!update_timer_.IsRunning()) {
100 update_timer_.Start(FROM_HERE, 108 update_timer_.Start(FROM_HERE,
101 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs), 109 base::TimeDelta::FromMilliseconds(kUpdatePeriodMs),
102 this, &DownloadFileManager::UpdateInProgressDownloads); 110 this, &DownloadFileManager::UpdateInProgressDownloads);
103 } 111 }
104 } 112 }
105 113
106 void DownloadFileManager::StopUpdateTimer() { 114 void DownloadFileManager::StopUpdateTimer() {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
108 update_timer_.Stop(); 116 update_timer_.Stop();
109 } 117 }
110 118
111 void DownloadFileManager::UpdateInProgressDownloads() { 119 void DownloadFileManager::UpdateInProgressDownloads() {
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
113 for (DownloadFileMap::iterator i = downloads_.begin(); 121 for (DownloadFileMap::iterator i = downloads_.begin();
114 i != downloads_.end(); ++i) { 122 i != downloads_.end(); ++i) {
115 DownloadId global_id = i->first; 123 DownloadId global_id = i->first;
116 DownloadFile* download_file = i->second; 124 DownloadFile* download_file = i->second;
117 DownloadManager* manager = download_file->GetDownloadManager(); 125 DownloadManager* manager = download_file->GetDownloadManager();
118 if (manager) { 126 if (manager) {
119 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 127 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
120 base::Bind(&DownloadManager::UpdateDownload, manager, 128 base::Bind(&DownloadManager::UpdateDownload, manager,
121 global_id.local(), download_file->bytes_so_far())); 129 global_id.local(), download_file->BytesSoFar()));
122 } 130 }
123 } 131 }
124 } 132 }
125 133
126 void DownloadFileManager::StartDownload( 134 void DownloadFileManager::StartDownload(
127 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) { 135 DownloadCreateInfo* info, const DownloadRequestHandle& request_handle) {
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
129 DCHECK(info); 137 DCHECK(info);
130 138
131 DownloadManager* manager = request_handle.GetDownloadManager(); 139 DownloadManager* manager = request_handle.GetDownloadManager();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 net::IOBuffer* data = (*contents)[i].first; 173 net::IOBuffer* data = (*contents)[i].first;
166 const int data_len = (*contents)[i].second; 174 const int data_len = (*contents)[i].second;
167 if (!had_error && download_file) { 175 if (!had_error && download_file) {
168 net::Error write_result = 176 net::Error write_result =
169 download_file->AppendDataToFile(data->data(), data_len); 177 download_file->AppendDataToFile(data->data(), data_len);
170 if (write_result != net::OK) { 178 if (write_result != net::OK) {
171 // Write failed: interrupt the download. 179 // Write failed: interrupt the download.
172 DownloadManager* download_manager = download_file->GetDownloadManager(); 180 DownloadManager* download_manager = download_file->GetDownloadManager();
173 had_error = true; 181 had_error = true;
174 182
175 int64 bytes_downloaded = download_file->bytes_so_far(); 183 int64 bytes_downloaded = download_file->BytesSoFar();
176 // Calling this here in case we get more data, to avoid 184 // Calling this here in case we get more data, to avoid
177 // processing data after an error. That could lead to 185 // processing data after an error. That could lead to
178 // files that are corrupted if the later processing succeeded. 186 // files that are corrupted if the later processing succeeded.
179 CancelDownload(global_id); 187 CancelDownload(global_id);
180 download_file = NULL; // Was deleted in |CancelDownload|. 188 download_file = NULL; // Was deleted in |CancelDownload|.
181 189
182 if (download_manager) { 190 if (download_manager) {
183 BrowserThread::PostTask( 191 BrowserThread::PostTask(
184 BrowserThread::UI, FROM_HERE, 192 BrowserThread::UI, FROM_HERE,
185 base::Bind(&DownloadManager::OnDownloadInterrupted, 193 base::Bind(&DownloadManager::OnDownloadInterrupted,
(...skipping 29 matching lines...) Expand all
215 223
216 std::string hash; 224 std::string hash;
217 if (!download_file->GetSha256Hash(&hash)) 225 if (!download_file->GetSha256Hash(&hash))
218 hash.clear(); 226 hash.clear();
219 227
220 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) { 228 if (reason == DOWNLOAD_INTERRUPT_REASON_NONE) {
221 BrowserThread::PostTask( 229 BrowserThread::PostTask(
222 BrowserThread::UI, FROM_HERE, 230 BrowserThread::UI, FROM_HERE,
223 base::Bind(&DownloadManager::OnResponseCompleted, 231 base::Bind(&DownloadManager::OnResponseCompleted,
224 download_manager, global_id.local(), 232 download_manager, global_id.local(),
225 download_file->bytes_so_far(), hash)); 233 download_file->BytesSoFar(), hash));
226 } else { 234 } else {
227 BrowserThread::PostTask( 235 BrowserThread::PostTask(
228 BrowserThread::UI, FROM_HERE, 236 BrowserThread::UI, FROM_HERE,
229 base::Bind(&DownloadManager::OnDownloadInterrupted, 237 base::Bind(&DownloadManager::OnDownloadInterrupted,
230 download_manager, global_id.local(), 238 download_manager, global_id.local(),
231 download_file->bytes_so_far(), reason)); 239 download_file->BytesSoFar(), reason));
232 } 240 }
233 // We need to keep the download around until the UI thread has finalized 241 // We need to keep the download around until the UI thread has finalized
234 // the name. 242 // the name.
235 } 243 }
236 244
237 // This method will be sent via a user action, or shutdown on the UI thread, and 245 // This method will be sent via a user action, or shutdown on the UI thread, and
238 // run on the download thread. Since this message has been sent from the UI 246 // run on the download thread. Since this message has been sent from the UI
239 // thread, the download may have already completed and won't exist in our map. 247 // thread, the download may have already completed and won't exist in our map.
240 void DownloadFileManager::CancelDownload(DownloadId global_id) { 248 void DownloadFileManager::CancelDownload(DownloadId global_id) {
241 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id; 249 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 i != downloads_.end(); ++i) { 287 i != downloads_.end(); ++i) {
280 DownloadFile* download_file = i->second; 288 DownloadFile* download_file = i->second;
281 if (download_file->GetDownloadManager() == manager) { 289 if (download_file->GetDownloadManager() == manager) {
282 download_file->CancelDownloadRequest(); 290 download_file->CancelDownloadRequest();
283 to_remove.insert(download_file); 291 to_remove.insert(download_file);
284 } 292 }
285 } 293 }
286 294
287 for (std::set<DownloadFile*>::iterator i = to_remove.begin(); 295 for (std::set<DownloadFile*>::iterator i = to_remove.begin();
288 i != to_remove.end(); ++i) { 296 i != to_remove.end(); ++i) {
289 downloads_.erase((*i)->global_id()); 297 downloads_.erase((*i)->GlobalId());
290 delete *i; 298 delete *i;
291 } 299 }
292 } 300 }
293 301
294 // Actions from the UI thread and run on the download thread 302 // Actions from the UI thread and run on the download thread
295 303
296 // The DownloadManager in the UI thread has provided an intermediate .crdownload 304 // The DownloadManager in the UI thread has provided an intermediate .crdownload
297 // name for the download specified by 'id'. Rename the in progress download. 305 // name for the download specified by 'id'. Rename the in progress download.
298 // 306 //
299 // There are 2 possible rename cases where this method can be called: 307 // There are 2 possible rename cases where this method can be called:
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 // need to do it here. The normal path will also update the download 407 // need to do it here. The normal path will also update the download
400 // history before canceling the request. 408 // history before canceling the request.
401 download_file->CancelDownloadRequest(); 409 download_file->CancelDownloadRequest();
402 return; 410 return;
403 } 411 }
404 412
405 BrowserThread::PostTask( 413 BrowserThread::PostTask(
406 BrowserThread::UI, FROM_HERE, 414 BrowserThread::UI, FROM_HERE,
407 base::Bind(&DownloadManager::OnDownloadInterrupted, 415 base::Bind(&DownloadManager::OnDownloadInterrupted,
408 download_manager, global_id.local(), 416 download_manager, global_id.local(),
409 download_file->bytes_so_far(), 417 download_file->BytesSoFar(),
410 ConvertNetErrorToInterruptReason( 418 ConvertNetErrorToInterruptReason(
411 rename_error, DOWNLOAD_INTERRUPT_FROM_DISK))); 419 rename_error, DOWNLOAD_INTERRUPT_FROM_DISK)));
412 } 420 }
413 421
414 void DownloadFileManager::EraseDownload(DownloadId global_id) { 422 void DownloadFileManager::EraseDownload(DownloadId global_id) {
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
416 424
417 if (!ContainsKey(downloads_, global_id)) 425 if (!ContainsKey(downloads_, global_id))
418 return; 426 return;
419 427
420 DownloadFile* download_file = downloads_[global_id]; 428 DownloadFile* download_file = downloads_[global_id];
421 429
422 VLOG(20) << " " << __FUNCTION__ << "()" 430 VLOG(20) << " " << __FUNCTION__ << "()"
423 << " id = " << global_id 431 << " id = " << global_id
424 << " download_file = " << download_file->DebugString(); 432 << " download_file = " << download_file->DebugString();
425 433
426 downloads_.erase(global_id); 434 downloads_.erase(global_id);
427 435
428 delete download_file; 436 delete download_file;
429 437
430 if (downloads_.empty()) 438 if (downloads_.empty())
431 StopUpdateTimer(); 439 StopUpdateTimer();
432 } 440 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698