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