OLD | NEW |
---|---|
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_resource_handler.h" | 5 #include "content/browser/download/download_resource_handler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
27 #include "net/base/io_buffer.h" | 27 #include "net/base/io_buffer.h" |
28 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
29 #include "net/http/http_response_headers.h" | 29 #include "net/http/http_response_headers.h" |
30 #include "net/url_request/url_request_context.h" | 30 #include "net/url_request/url_request_context.h" |
31 | 31 |
32 using content::BrowserThread; | 32 using content::BrowserThread; |
33 using content::DownloadId; | 33 using content::DownloadId; |
34 using content::DownloadItem; | 34 using content::DownloadItem; |
35 using content::DownloadManager; | 35 using content::DownloadManager; |
36 | 36 |
37 namespace { | |
38 | |
39 void CallStartedCBOnUIThread( | |
40 const DownloadResourceHandler::OnStartedCallback& started_cb, | |
41 DownloadId id, | |
42 net::Error error) { | |
43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
44 if (started_cb.is_null()) | |
Randy Smith (Not in Mondays)
2012/03/07 21:16:57
When you null a callback, doesn't that mean that r
ahendrickson
2012/03/08 21:33:07
I tried it, and got a NULL function pointer which
Randy Smith (Not in Mondays)
2012/03/09 19:14:02
I spent a bit of time digging around to see if the
| |
45 return; | |
46 started_cb.Run(id, error); | |
47 } | |
48 | |
49 } // namespace | |
50 | |
37 DownloadResourceHandler::DownloadResourceHandler( | 51 DownloadResourceHandler::DownloadResourceHandler( |
38 ResourceDispatcherHost* rdh, | 52 ResourceDispatcherHost* rdh, |
39 int render_process_host_id, | 53 int render_process_host_id, |
40 int render_view_id, | 54 int render_view_id, |
41 int request_id, | 55 int request_id, |
42 const GURL& url, | 56 const GURL& url, |
43 DownloadFileManager* download_file_manager, | 57 DownloadFileManager* download_file_manager, |
44 net::URLRequest* request, | 58 net::URLRequest* request, |
45 const DownloadResourceHandler::OnStartedCallback& started_cb, | 59 const DownloadResourceHandler::OnStartedCallback& started_cb, |
46 const DownloadSaveInfo& save_info) | 60 const DownloadSaveInfo& save_info) |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
152 | 166 |
153 // We can't start saving the data before we create the file on disk and have a | 167 // We can't start saving the data before we create the file on disk and have a |
154 // download id. The request will be un-paused in | 168 // download id. The request will be un-paused in |
155 // DownloadFileManager::CreateDownloadFile. | 169 // DownloadFileManager::CreateDownloadFile. |
156 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, true); | 170 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, true); |
157 | 171 |
158 return true; | 172 return true; |
159 } | 173 } |
160 | 174 |
161 void DownloadResourceHandler::CallStartedCB(DownloadId id, net::Error error) { | 175 void DownloadResourceHandler::CallStartedCB(DownloadId id, net::Error error) { |
162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
163 if (started_cb_.is_null()) | 176 if (started_cb_.is_null()) |
164 return; | 177 return; |
165 started_cb_.Run(id, error); | 178 BrowserThread::PostTask( |
179 BrowserThread::UI, FROM_HERE, | |
180 base::Bind(&CallStartedCBOnUIThread, started_cb_, id, error)); | |
Randy Smith (Not in Mondays)
2012/03/07 21:16:57
As noted elsewhere, I think this can be simplified
| |
166 started_cb_.Reset(); | 181 started_cb_.Reset(); |
167 } | 182 } |
168 | 183 |
169 bool DownloadResourceHandler::OnWillStart(int request_id, | 184 bool DownloadResourceHandler::OnWillStart(int request_id, |
170 const GURL& url, | 185 const GURL& url, |
171 bool* defer) { | 186 bool* defer) { |
172 return true; | 187 return true; |
173 } | 188 } |
174 | 189 |
175 // Create a new buffer, which will be handed to the download thread for file | 190 // Create a new buffer, which will be handed to the download thread for file |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 default: | 306 default: |
292 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; | 307 reason = DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED; |
293 break; | 308 break; |
294 } | 309 } |
295 } | 310 } |
296 } | 311 } |
297 | 312 |
298 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_); | 313 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_); |
299 | 314 |
300 // If the callback was already run on the UI thread, this will be a noop. | 315 // If the callback was already run on the UI thread, this will be a noop. |
301 BrowserThread::PostTask( | 316 CallStartedCB(download_id_, error_code); |
302 BrowserThread::UI, FROM_HERE, | |
303 base::Bind(&DownloadResourceHandler::CallStartedCB, this, | |
304 download_id_, error_code)); | |
305 | 317 |
306 // We transfer ownership to |DownloadFileManager| to delete |buffer_|, | 318 // We transfer ownership to |DownloadFileManager| to delete |buffer_|, |
307 // so that any functions queued up on the FILE thread are executed | 319 // so that any functions queued up on the FILE thread are executed |
308 // before deletion. | 320 // before deletion. |
309 BrowserThread::PostTask( | 321 BrowserThread::PostTask( |
310 BrowserThread::FILE, FROM_HERE, | 322 BrowserThread::FILE, FROM_HERE, |
311 base::Bind(&DownloadFileManager::OnResponseCompleted, | 323 base::Bind(&DownloadFileManager::OnResponseCompleted, |
312 download_file_manager_, download_id_, reason, security_info)); | 324 download_file_manager_, download_id_, reason, security_info)); |
313 buffer_ = NULL; // The buffer is longer needed by |DownloadResourceHandler|. | 325 buffer_ = NULL; // The buffer is longer needed by |DownloadResourceHandler|. |
314 read_buffer_ = NULL; | 326 read_buffer_ = NULL; |
315 } | 327 } |
316 | 328 |
317 void DownloadResourceHandler::OnRequestClosed() { | 329 void DownloadResourceHandler::OnRequestClosed() { |
318 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", | 330 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", |
319 base::TimeTicks::Now() - download_start_time_); | 331 base::TimeTicks::Now() - download_start_time_); |
320 } | 332 } |
321 | 333 |
322 void DownloadResourceHandler::StartOnUIThread( | 334 void DownloadResourceHandler::StartOnUIThread( |
323 scoped_ptr<DownloadCreateInfo> info, | 335 scoped_ptr<DownloadCreateInfo> info, |
324 const DownloadRequestHandle& handle) { | 336 const DownloadRequestHandle& handle) { |
325 DownloadManager* download_manager = handle.GetDownloadManager(); | 337 DownloadManager* download_manager = handle.GetDownloadManager(); |
326 if (!download_manager) { | 338 if (!download_manager) { |
327 // NULL in unittests or if the page closed right after starting the | 339 // NULL in unittests or if the page closed right after starting the |
328 // download. | 340 // download. |
341 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED); | |
329 return; | 342 return; |
330 } | 343 } |
331 DownloadId download_id = download_manager->delegate()->GetNextId(); | 344 DownloadId download_id = download_manager->delegate()->GetNextId(); |
332 info->download_id = download_id; | 345 info->download_id = download_id; |
333 BrowserThread::PostTask( | 346 BrowserThread::PostTask( |
334 BrowserThread::IO, FROM_HERE, | 347 BrowserThread::IO, FROM_HERE, |
335 base::Bind(&DownloadResourceHandler::set_download_id, this, | 348 base::Bind(&DownloadResourceHandler::set_download_id, this, |
336 info->download_id)); | 349 info->download_id)); |
337 // It's safe to continue on with download initiation before we have | 350 // It's safe to continue on with download initiation before we have |
338 // confirmation that that download_id_ has been set on the IO thread, as any | 351 // confirmation that that download_id_ has been set on the IO thread, as any |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 StartPauseTimer(); | 387 StartPauseTimer(); |
375 | 388 |
376 if (is_paused_ != should_pause) { | 389 if (is_paused_ != should_pause) { |
377 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, | 390 rdh_->PauseRequest(global_id_.child_id, global_id_.request_id, |
378 should_pause); | 391 should_pause); |
379 is_paused_ = should_pause; | 392 is_paused_ = should_pause; |
380 } | 393 } |
381 } | 394 } |
382 | 395 |
383 DownloadResourceHandler::~DownloadResourceHandler() { | 396 DownloadResourceHandler::~DownloadResourceHandler() { |
397 // This won't do anything if the callback was called before. | |
398 // If it goes through, it will likely be because OnWillStart() returned | |
399 // false somewhere in the chain of resource handlers. | |
400 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED); | |
384 } | 401 } |
385 | 402 |
386 void DownloadResourceHandler::StartPauseTimer() { | 403 void DownloadResourceHandler::StartPauseTimer() { |
387 if (!pause_timer_.IsRunning()) | 404 if (!pause_timer_.IsRunning()) |
388 pause_timer_.Start(FROM_HERE, | 405 pause_timer_.Start(FROM_HERE, |
389 base::TimeDelta::FromMilliseconds(kThrottleTimeMs), this, | 406 base::TimeDelta::FromMilliseconds(kThrottleTimeMs), this, |
390 &DownloadResourceHandler::CheckWriteProgress); | 407 &DownloadResourceHandler::CheckWriteProgress); |
391 } | 408 } |
392 | 409 |
393 std::string DownloadResourceHandler::DebugString() const { | 410 std::string DownloadResourceHandler::DebugString() const { |
394 return base::StringPrintf("{" | 411 return base::StringPrintf("{" |
395 " url_ = " "\"%s\"" | 412 " url_ = " "\"%s\"" |
396 " download_id_ = " "%d" | 413 " download_id_ = " "%d" |
397 " global_id_ = {" | 414 " global_id_ = {" |
398 " child_id = " "%d" | 415 " child_id = " "%d" |
399 " request_id = " "%d" | 416 " request_id = " "%d" |
400 " }" | 417 " }" |
401 " render_view_id_ = " "%d" | 418 " render_view_id_ = " "%d" |
402 " save_info_.file_path = \"%" PRFilePath "\"" | 419 " save_info_.file_path = \"%" PRFilePath "\"" |
403 " }", | 420 " }", |
404 request_->url().spec().c_str(), | 421 request_ ? |
422 request_->url().spec().c_str() : | |
423 "<NULL request>", | |
405 download_id_.local(), | 424 download_id_.local(), |
406 global_id_.child_id, | 425 global_id_.child_id, |
407 global_id_.request_id, | 426 global_id_.request_id, |
408 render_view_id_, | 427 render_view_id_, |
409 save_info_.file_path.value().c_str()); | 428 save_info_.file_path.value().c_str()); |
410 } | 429 } |
OLD | NEW |