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

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

Powered by Google App Engine
This is Rietveld 408576698