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

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

Issue 10074001: Initial implementation of the ByteStream refactor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Checkpoint and merge to LKGR. Created 8 years, 7 months 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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"
17 #include "content/browser/download/download_create_info.h" 16 #include "content/browser/download/download_create_info.h"
18 #include "content/browser/download/download_file_impl.h" 17 #include "content/browser/download/download_file_impl.h"
19 #include "content/browser/download/download_interrupt_reasons_impl.h" 18 #include "content/browser/download/download_interrupt_reasons_impl.h"
20 #include "content/browser/download/download_request_handle.h" 19 #include "content/browser/download/download_request_handle.h"
21 #include "content/browser/download/download_stats.h" 20 #include "content/browser/download/download_stats.h"
22 #include "content/browser/power_save_blocker.h" 21 #include "content/browser/power_save_blocker.h"
23 #include "content/browser/web_contents/web_contents_impl.h" 22 #include "content/browser/web_contents/web_contents_impl.h"
24 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/download_manager.h" 24 #include "content/public/browser/download_manager.h"
26 #include "content/public/browser/download_manager_delegate.h" 25 #include "content/public/browser/download_manager_delegate.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 &DownloadManager::OnDownloadInterrupted, 110 &DownloadManager::OnDownloadInterrupted,
112 download_manager, 111 download_manager,
113 info->download_id.local(), 112 info->download_id.local(),
114 0, 113 0,
115 "", 114 "",
116 content::ConvertNetErrorToInterruptReason( 115 content::ConvertNetErrorToInterruptReason(
117 init_result, content::DOWNLOAD_INTERRUPT_FROM_DISK))); 116 init_result, content::DOWNLOAD_INTERRUPT_FROM_DISK)));
118 } else { 117 } else {
119 DCHECK(GetDownloadFile(info->download_id) == NULL); 118 DCHECK(GetDownloadFile(info->download_id) == NULL);
120 downloads_[info->download_id] = download_file.release(); 119 downloads_[info->download_id] = download_file.release();
121
122 // The file is now ready, we can un-pause the request and start saving data.
123 request_handle.ResumeRequest();
124 } 120 }
125 121
126 BrowserThread::PostTask( 122 BrowserThread::PostTask(
127 BrowserThread::UI, FROM_HERE, 123 BrowserThread::UI, FROM_HERE,
128 base::Bind(&DownloadManager::StartDownload, download_manager, 124 base::Bind(&DownloadManager::StartDownload, download_manager,
129 info->download_id.local())); 125 info->download_id.local()));
130 } 126 }
131 127
132 DownloadFile* DownloadFileManager::GetDownloadFile( 128 DownloadFile* DownloadFileManager::GetDownloadFile(
133 DownloadId global_id) { 129 DownloadId global_id) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 net::BoundNetLog bound_net_log = 163 net::BoundNetLog bound_net_log =
168 manager->CreateDownloadItem(info, request_handle); 164 manager->CreateDownloadItem(info, request_handle);
169 bool hash_needed = manager->GenerateFileHash(); 165 bool hash_needed = manager->GenerateFileHash();
170 166
171 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 167 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
172 base::Bind(&DownloadFileManager::CreateDownloadFile, this, 168 base::Bind(&DownloadFileManager::CreateDownloadFile, this,
173 info, request_handle, make_scoped_refptr(manager), 169 info, request_handle, make_scoped_refptr(manager),
174 hash_needed, bound_net_log)); 170 hash_needed, bound_net_log));
175 } 171 }
176 172
177 // We don't forward an update to the UI thread here, since we want to throttle
178 // the UI update rate via a periodic timer. If the user has cancelled the
179 // download (in the UI thread), we may receive a few more updates before the IO
180 // thread gets the cancel message: we just delete the data since the
181 // DownloadFile has been deleted.
182 void DownloadFileManager::UpdateDownload(
183 DownloadId global_id, content::DownloadBuffer* buffer) {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
185 scoped_ptr<content::ContentVector> contents(buffer->ReleaseContents());
186
187 download_stats::RecordFileThreadReceiveBuffers(contents->size());
188
189 DownloadFile* download_file = GetDownloadFile(global_id);
190 bool had_error = false;
191 for (size_t i = 0; i < contents->size(); ++i) {
192 net::IOBuffer* data = (*contents)[i].first;
193 const int data_len = (*contents)[i].second;
194 if (!had_error && download_file) {
195 net::Error write_result =
196 download_file->AppendDataToFile(data->data(), data_len);
197 if (write_result != net::OK) {
198 // Write failed: interrupt the download.
199 DownloadManager* download_manager =
200 download_file->GetDownloadManager();
201 had_error = true;
202
203 int64 bytes_downloaded = download_file->BytesSoFar();
204 std::string hash_state(download_file->GetHashState());
205
206 // Calling this here in case we get more data, to avoid
207 // processing data after an error. That could lead to
208 // files that are corrupted if the later processing succeeded.
209 CancelDownload(global_id);
210 download_file = NULL; // Was deleted in |CancelDownload|.
211
212 if (download_manager) {
213 BrowserThread::PostTask(
214 BrowserThread::UI, FROM_HERE,
215 base::Bind(&DownloadManager::OnDownloadInterrupted,
216 download_manager,
217 global_id.local(),
218 bytes_downloaded,
219 hash_state,
220 content::ConvertNetErrorToInterruptReason(
221 write_result,
222 content::DOWNLOAD_INTERRUPT_FROM_DISK)));
223 }
224 }
225 }
226 data->Release();
227 }
228 }
229
230 void DownloadFileManager::OnResponseCompleted(
231 DownloadId global_id,
232 content::DownloadInterruptReason reason,
233 const std::string& security_info) {
234 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id
235 << " reason = " << InterruptReasonDebugString(reason)
236 << " security_info = \"" << security_info << "\"";
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
238 DownloadFile* download_file = GetDownloadFile(global_id);
239 if (!download_file)
240 return;
241
242 download_file->Finish();
243
244 DownloadManager* download_manager = download_file->GetDownloadManager();
245 if (!download_manager) {
246 CancelDownload(global_id);
247 return;
248 }
249
250 if (reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) {
251 std::string hash;
252 if (!download_file->GetHash(&hash) ||
253 BaseFile::IsEmptyHash(hash)) {
254 hash.clear();
255 }
256
257 BrowserThread::PostTask(
258 BrowserThread::UI, FROM_HERE,
259 base::Bind(&DownloadManager::OnResponseCompleted,
260 download_manager, global_id.local(),
261 download_file->BytesSoFar(), hash));
262 } else {
263 BrowserThread::PostTask(
264 BrowserThread::UI, FROM_HERE,
265 base::Bind(&DownloadManager::OnDownloadInterrupted,
266 download_manager,
267 global_id.local(),
268 download_file->BytesSoFar(),
269 download_file->GetHashState(),
270 reason));
271 }
272 // We need to keep the download around until the UI thread has finalized
273 // the name.
274 }
275
276 // This method will be sent via a user action, or shutdown on the UI thread, and 173 // This method will be sent via a user action, or shutdown on the UI thread, and
277 // run on the download thread. Since this message has been sent from the UI 174 // run on the download thread. Since this message has been sent from the UI
278 // thread, the download may have already completed and won't exist in our map. 175 // thread, the download may have already completed and won't exist in our map.
279 void DownloadFileManager::CancelDownload(DownloadId global_id) { 176 void DownloadFileManager::CancelDownload(DownloadId global_id) {
280 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id; 177 VLOG(20) << __FUNCTION__ << "()" << " id = " << global_id;
281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
282 DownloadFileMap::iterator it = downloads_.find(global_id); 179 DownloadFileMap::iterator it = downloads_.find(global_id);
283 if (it == downloads_.end()) 180 if (it == downloads_.end())
284 return; 181 return;
285 182
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 DownloadFile* download_file = downloads_[global_id]; 361 DownloadFile* download_file = downloads_[global_id];
465 362
466 VLOG(20) << " " << __FUNCTION__ << "()" 363 VLOG(20) << " " << __FUNCTION__ << "()"
467 << " id = " << global_id 364 << " id = " << global_id
468 << " download_file = " << download_file->DebugString(); 365 << " download_file = " << download_file->DebugString();
469 366
470 downloads_.erase(global_id); 367 downloads_.erase(global_id);
471 368
472 delete download_file; 369 delete download_file;
473 } 370 }
OLDNEW
« no previous file with comments | « content/browser/download/download_file_manager.h ('k') | content/browser/download/download_file_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698