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

Side by Side Diff: chrome/browser/download/download_manager.cc

Issue 3127008: Preliminary work on resuming downloads whose connections have expired.
Patch Set: Waiting to send download automation error message until after other downloads are canceled. Created 10 years, 2 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/download/download_manager.h" 5 #include "chrome/browser/download/download_manager.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 68
69 if (file_manager_) { 69 if (file_manager_) {
70 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 70 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE,
71 NewRunnableMethod(file_manager_, 71 NewRunnableMethod(file_manager_,
72 &DownloadFileManager::OnDownloadManagerShutdown, 72 &DownloadFileManager::OnDownloadManagerShutdown,
73 this)); 73 this));
74 } 74 }
75 75
76 // 'in_progress_' may contain DownloadItems that have not finished the start 76 // 'in_progress_' may contain DownloadItems that have not finished the start
77 // complete (from the history service) and thus aren't in downloads_. 77 // complete (from the history service) and thus aren't in downloads_.
78 // It may also contain DownloadItems that have been interrupted.
78 DownloadMap::iterator it = in_progress_.begin(); 79 DownloadMap::iterator it = in_progress_.begin();
79 std::set<DownloadItem*> to_remove; 80 std::set<DownloadItem*> to_remove;
80 for (; it != in_progress_.end(); ++it) { 81 for (; it != in_progress_.end(); ++it) {
81 DownloadItem* download = it->second; 82 DownloadItem* download = it->second;
82 if (download->safety_state() == DownloadItem::DANGEROUS) { 83 if (download->safety_state() == DownloadItem::DANGEROUS) {
83 // Forget about any download that the user did not approve. 84 // Forget about any download that the user did not approve.
84 // Note that we cannot call download->Remove() this would invalidate our 85 // Note that we cannot call download->Remove() this would invalidate our
85 // iterator. 86 // iterator.
86 to_remove.insert(download); 87 to_remove.insert(download);
87 continue; 88 continue;
88 } 89 }
89 DCHECK_EQ(DownloadItem::IN_PROGRESS, download->state()); 90 DCHECK(download->IsPartialDownload());
90 download->Cancel(false); 91 download->Cancel(false);
91 download_history_->UpdateEntry(download); 92 download_history_->UpdateEntry(download);
92 if (download->db_handle() == DownloadHistory::kUninitializedHandle) { 93 if (download->db_handle() == DownloadHistory::kUninitializedHandle) {
93 // An invalid handle means that 'download' does not yet exist in 94 // An invalid handle means that 'download' does not yet exist in
94 // 'downloads_', so we have to delete it here. 95 // 'downloads_', so we have to delete it here.
95 delete download; 96 delete download;
96 } 97 }
97 } 98 }
98 99
99 // 'dangerous_finished_' contains all complete downloads that have not been 100 // 'dangerous_finished_' contains all complete downloads that have not been
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 } 162 }
162 } 163 }
163 164
164 void DownloadManager::GetCurrentDownloads( 165 void DownloadManager::GetCurrentDownloads(
165 const FilePath& dir_path, std::vector<DownloadItem*>* result) { 166 const FilePath& dir_path, std::vector<DownloadItem*>* result) {
166 DCHECK(result); 167 DCHECK(result);
167 168
168 for (DownloadMap::iterator it = downloads_.begin(); 169 for (DownloadMap::iterator it = downloads_.begin();
169 it != downloads_.end(); ++it) { 170 it != downloads_.end(); ++it) {
170 if (!it->second->is_temporary() && 171 if (!it->second->is_temporary() &&
171 (it->second->state() == DownloadItem::IN_PROGRESS || 172 (it->second->IsPartialDownload() ||
172 it->second->safety_state() == DownloadItem::DANGEROUS) && 173 (it->second->safety_state() == DownloadItem::DANGEROUS)) &&
173 (dir_path.empty() || it->second->full_path().DirName() == dir_path)) 174 (dir_path.empty() ||
175 (it->second->full_path().DirName() == dir_path))) {
174 result->push_back(it->second); 176 result->push_back(it->second);
177 }
175 } 178 }
176 } 179 }
177 180
178 void DownloadManager::SearchDownloads(const string16& query, 181 void DownloadManager::SearchDownloads(const string16& query,
179 std::vector<DownloadItem*>* result) { 182 std::vector<DownloadItem*>* result) {
180 DCHECK(result); 183 DCHECK(result);
181 184
182 string16 query_lower(l10n_util::ToLower(query)); 185 string16 query_lower(l10n_util::ToLower(query));
183 186
184 for (DownloadMap::iterator it = downloads_.begin(); 187 for (DownloadMap::iterator it = downloads_.begin();
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 else if (info->is_extension_install && 297 else if (info->is_extension_install &&
295 !ExtensionsService::IsDownloadFromGallery(info->url, 298 !ExtensionsService::IsDownloadFromGallery(info->url,
296 info->referrer_url)) { 299 info->referrer_url)) {
297 info->is_dangerous = true; 300 info->is_dangerous = true;
298 } 301 }
299 } 302 }
300 303
301 // We need to move over to the download thread because we don't want to stat 304 // We need to move over to the download thread because we don't want to stat
302 // the suggested path on the UI thread. 305 // the suggested path on the UI thread.
303 ChromeThread::PostTask( 306 ChromeThread::PostTask(
304 ChromeThread::FILE, FROM_HERE, 307 ChromeThread::FILE,
308 FROM_HERE,
305 NewRunnableMethod( 309 NewRunnableMethod(
306 this, &DownloadManager::CheckIfSuggestedPathExists, info)); 310 this, &DownloadManager::CheckIfSuggestedPathExists, info));
307 } 311 }
308 312
309 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { 313 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
310 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE)); 314 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
311 DCHECK(info); 315 DCHECK(info);
312 316
313 // Check writability of the suggested path. If we can't write to it, default 317 // Check writability of the suggested path. If we can't write to it, default
314 // to the user's "My Documents" directory. We'll prompt them in this case. 318 // to the user's "My Documents" directory. We'll prompt them in this case.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 if (!info->prompt_user_for_save_location && 365 if (!info->prompt_user_for_save_location &&
362 info->save_info.file_path.empty()) { 366 info->save_info.file_path.empty()) {
363 if (info->is_dangerous) 367 if (info->is_dangerous)
364 file_util::WriteFile(info->suggested_path, "", 0); 368 file_util::WriteFile(info->suggested_path, "", 0);
365 else 369 else
366 file_util::WriteFile(download_util::GetCrDownloadPath( 370 file_util::WriteFile(download_util::GetCrDownloadPath(
367 info->suggested_path), "", 0); 371 info->suggested_path), "", 0);
368 } 372 }
369 373
370 ChromeThread::PostTask( 374 ChromeThread::PostTask(
371 ChromeThread::UI, FROM_HERE, 375 ChromeThread::UI,
376 FROM_HERE,
372 NewRunnableMethod(this, 377 NewRunnableMethod(this,
373 &DownloadManager::OnPathExistenceAvailable, 378 &DownloadManager::OnPathExistenceAvailable,
374 info)); 379 info));
375 } 380 }
376 381
377 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { 382 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
378 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 383 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
379 DCHECK(info); 384 DCHECK(info);
380 385
381 if (info->prompt_user_for_save_location) { 386 if (info->prompt_user_for_save_location) {
(...skipping 22 matching lines...) Expand all
404 } 409 }
405 } 410 }
406 411
407 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info, 412 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info,
408 const FilePath& target_path) { 413 const FilePath& target_path) {
409 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 414 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
410 415
411 scoped_ptr<DownloadCreateInfo> infop(info); 416 scoped_ptr<DownloadCreateInfo> infop(info);
412 info->path = target_path; 417 info->path = target_path;
413 418
414 DownloadItem* download = new DownloadItem(this, *info, 419 DownloadItem* download = NULL;
415 profile_->IsOffTheRecord()); 420 // For partial downloads, reuse the existing DownloadItem.
416 DCHECK(!ContainsKey(in_progress_, info->download_id)); 421 if (info->is_partial_download && (info->download_id != -1)) {
417 in_progress_[info->download_id] = download; 422 DownloadMap::iterator it = in_progress_.find(info->download_id);
423 if (it != in_progress_.end()) {
424 download = it->second;
425 download->Resumed(info->request_id);
426 }
427 }
428 if (!download) {
429 download = new DownloadItem(this, *info, profile_->IsOffTheRecord());
430 DCHECK(!ContainsKey(in_progress_, info->download_id));
431 in_progress_[info->download_id] = download;
432 }
418 433
419 bool download_finished = ContainsKey(pending_finished_downloads_, 434 bool download_finished = ContainsKey(pending_finished_downloads_,
420 info->download_id); 435 info->download_id);
421 436
422 if (download_finished || info->is_dangerous) { 437 if (download_finished || info->is_dangerous) {
423 // The download has already finished or the download is not safe. 438 // The download has already finished or the download is not safe.
424 // We can now rename the file to its final name (or its tentative name 439 // We can now rename the file to its final name (or its tentative name
425 // in dangerous download cases). 440 // in dangerous download cases).
426 ChromeThread::PostTask( 441 ChromeThread::PostTask(
427 ChromeThread::FILE, FROM_HERE, 442 ChromeThread::FILE,
443 FROM_HERE,
428 NewRunnableMethod( 444 NewRunnableMethod(
429 file_manager_, &DownloadFileManager::OnFinalDownloadName, 445 file_manager_, &DownloadFileManager::OnFinalDownloadName,
430 download->id(), target_path, !info->is_dangerous, this)); 446 download->id(), target_path, !info->is_dangerous, this));
431 } else { 447 } else {
432 // The download hasn't finished and it is a safe download. We need to 448 // The download hasn't finished and it is a safe download. We need to
433 // rename it to its intermediate '.crdownload' path. 449 // rename it to its intermediate '.crdownload' path.
434 FilePath download_path = download_util::GetCrDownloadPath(target_path); 450 FilePath download_path = download_util::GetCrDownloadPath(target_path);
435 ChromeThread::PostTask( 451 ChromeThread::PostTask(
436 ChromeThread::FILE, FROM_HERE, 452 ChromeThread::FILE,
453 FROM_HERE,
437 NewRunnableMethod( 454 NewRunnableMethod(
438 file_manager_, &DownloadFileManager::OnIntermediateDownloadName, 455 file_manager_, &DownloadFileManager::OnIntermediateDownloadName,
439 download->id(), download_path, this)); 456 download->id(), download_path, this));
440 download->set_need_final_rename(true); 457 download->set_need_final_rename(true);
441 } 458 }
442 459
443 if (download_finished) { 460 if (download_finished) {
444 // If the download already completed by the time we reached this point, then 461 // If the download already completed by the time we reached this point, then
445 // notify observers that it did. 462 // notify observers that it did.
446 OnAllDataSaved(info->download_id, 463 OnAllDataSaved(info->download_id,
(...skipping 11 matching lines...) Expand all
458 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { 475 void DownloadManager::UpdateDownload(int32 download_id, int64 size) {
459 DownloadMap::iterator it = in_progress_.find(download_id); 476 DownloadMap::iterator it = in_progress_.find(download_id);
460 if (it != in_progress_.end()) { 477 if (it != in_progress_.end()) {
461 DownloadItem* download = it->second; 478 DownloadItem* download = it->second;
462 download->Update(size); 479 download->Update(size);
463 download_history_->UpdateEntry(download); 480 download_history_->UpdateEntry(download);
464 } 481 }
465 UpdateAppIcon(); 482 UpdateAppIcon();
466 } 483 }
467 484
485 void DownloadManager::OnResponseCompleted(int32 download_id,
486 int64 size,
487 int os_error) {
488 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
489 if (os_error == 0) {
490 OnAllDataSaved(download_id, size);
491 } else {
492 DownloadError(download_id, size, os_error);
493 }
494 }
495
468 void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) { 496 void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) {
469 DownloadMap::iterator it = in_progress_.find(download_id); 497 DownloadMap::iterator it = in_progress_.find(download_id);
470 if (it == in_progress_.end()) { 498 if (it == in_progress_.end()) {
471 // The download is done, but the user hasn't selected a final location for 499 // The download is done, but the user hasn't selected a final location for
472 // it yet (the Save As dialog box is probably still showing), so just keep 500 // it yet (the Save As dialog box is probably still showing), so just keep
473 // track of the fact that this download id is complete, when the 501 // track of the fact that this download id is complete, when the
474 // DownloadItem is constructed later we'll notify its completion then. 502 // DownloadItem is constructed later we'll notify its completion then.
475 PendingFinishedMap::iterator erase_it = 503 PendingFinishedMap::iterator erase_it =
476 pending_finished_downloads_.find(download_id); 504 pending_finished_downloads_.find(download_id);
477 DCHECK(erase_it == pending_finished_downloads_.end()); 505 DCHECK(erase_it == pending_finished_downloads_.end());
(...skipping 24 matching lines...) Expand all
502 // ProceedWithFinishedDangerousDownload. 530 // ProceedWithFinishedDangerousDownload.
503 if (download->safety_state() == DownloadItem::DANGEROUS) { 531 if (download->safety_state() == DownloadItem::DANGEROUS) {
504 dangerous_finished_[download_id] = download; 532 dangerous_finished_[download_id] = download;
505 return; 533 return;
506 } 534 }
507 535
508 if (download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) { 536 if (download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
509 // We first need to rename the downloaded file from its temporary name to 537 // We first need to rename the downloaded file from its temporary name to
510 // its final name before we can continue. 538 // its final name before we can continue.
511 ChromeThread::PostTask( 539 ChromeThread::PostTask(
512 ChromeThread::FILE, FROM_HERE, 540 ChromeThread::FILE,
541 FROM_HERE,
513 NewRunnableMethod( 542 NewRunnableMethod(
514 this, &DownloadManager::ProceedWithFinishedDangerousDownload, 543 this, &DownloadManager::ProceedWithFinishedDangerousDownload,
515 download->db_handle(), 544 download->db_handle(),
516 download->full_path(), download->original_name())); 545 download->full_path(), download->original_name()));
517 return; 546 return;
518 } 547 }
519 548
520 if (download->need_final_rename()) { 549 if (download->need_final_rename()) {
521 ChromeThread::PostTask( 550 ChromeThread::PostTask(
522 ChromeThread::FILE, FROM_HERE, 551 ChromeThread::FILE,
552 FROM_HERE,
523 NewRunnableMethod( 553 NewRunnableMethod(
524 file_manager_, &DownloadFileManager::OnFinalDownloadName, 554 file_manager_, &DownloadFileManager::OnFinalDownloadName,
525 download->id(), download->full_path(), false, this)); 555 download->id(), download->full_path(), false, this));
526 return; 556 return;
527 } 557 }
528 558
529 ContinueDownloadFinished(download); 559 ContinueDownloadFinished(download);
530 } 560 }
531 561
562 void DownloadManager::DownloadError(int32 download_id,
563 int64 size,
564 int os_error) {
565 DownloadMap::iterator it = in_progress_.find(download_id);
566 // If enough time passes, the download item could be
567 // removed from the |in_progress_| map before we get here.
568 if (it == in_progress_.end())
569 return;
570
571 DownloadItem* download = it->second;
572 download->Interrupted(size, os_error);
573
574 LOG(INFO) << "Error " << download->last_os_error() << " at offset "
575 << download->received_bytes() << " for file at \""
576 << download->url().spec() << "\"";
577
578 // Clean up will happen when the history system create callback runs if we
579 // don't have a valid db_handle yet, and otherwise when we restart.
580 if (download->db_handle() != DownloadHistory::kUninitializedHandle)
581 download_history_->UpdateEntry(download);
582
583 UpdateAppIcon();
584
585 // Notify our observers that we are interrupted.
586 download->UpdateObservers();
587 }
588
532 void DownloadManager::DownloadRenamedToFinalName(int download_id, 589 void DownloadManager::DownloadRenamedToFinalName(int download_id,
533 const FilePath& full_path) { 590 const FilePath& full_path) {
534 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 591 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
535 592
536 DownloadItem* item = GetDownloadItem(download_id); 593 DownloadItem* item = GetDownloadItem(download_id);
537 if (!item) 594 if (!item)
538 return; 595 return;
539 item->OnNameFinalized(); 596 item->OnNameFinalized();
540 597
541 // This was called from DownloadFinished; continue to call 598 // This was called from DownloadFinished; continue to call
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 // file gets the same name. 630 // file gets the same name.
574 uniquifier = download_util::GetUniquePathNumber(new_path); 631 uniquifier = download_util::GetUniquePathNumber(new_path);
575 if (uniquifier > 0) 632 if (uniquifier > 0)
576 download_util::AppendNumberToPath(&new_path, uniquifier); 633 download_util::AppendNumberToPath(&new_path, uniquifier);
577 success = file_util::Move(path, new_path); 634 success = file_util::Move(path, new_path);
578 } else { 635 } else {
579 NOTREACHED(); 636 NOTREACHED();
580 } 637 }
581 638
582 ChromeThread::PostTask( 639 ChromeThread::PostTask(
583 ChromeThread::UI, FROM_HERE, 640 ChromeThread::UI,
641 FROM_HERE,
584 NewRunnableMethod(this, &DownloadManager::DangerousDownloadRenamed, 642 NewRunnableMethod(this, &DownloadManager::DangerousDownloadRenamed,
585 download_handle, success, new_path, uniquifier)); 643 download_handle, success, new_path, uniquifier));
586 } 644 }
587 645
588 // Call from the file thread when the finished dangerous download was renamed. 646 // Call from the file thread when the finished dangerous download was renamed.
589 void DownloadManager::DangerousDownloadRenamed(int64 download_handle, 647 void DownloadManager::DangerousDownloadRenamed(int64 download_handle,
590 bool success, 648 bool success,
591 const FilePath& new_path, 649 const FilePath& new_path,
592 int new_path_uniquifier) { 650 int new_path_uniquifier) {
593 DownloadMap::iterator it = downloads_.find(download_handle); 651 DownloadMap::iterator it = downloads_.find(download_handle);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 download->render_process_id(), 684 download->render_process_id(),
627 download->request_id()); 685 download->request_id());
628 UpdateAppIcon(); 686 UpdateAppIcon();
629 } 687 }
630 688
631 void DownloadManager::DownloadCancelledInternal(int download_id, 689 void DownloadManager::DownloadCancelledInternal(int download_id,
632 int render_process_id, 690 int render_process_id,
633 int request_id) { 691 int request_id) {
634 // Cancel the network request. RDH is guaranteed to outlive the IO thread. 692 // Cancel the network request. RDH is guaranteed to outlive the IO thread.
635 ChromeThread::PostTask( 693 ChromeThread::PostTask(
636 ChromeThread::IO, FROM_HERE, 694 ChromeThread::IO,
695 FROM_HERE,
637 NewRunnableFunction(&download_util::CancelDownloadRequest, 696 NewRunnableFunction(&download_util::CancelDownloadRequest,
638 g_browser_process->resource_dispatcher_host(), 697 g_browser_process->resource_dispatcher_host(),
639 render_process_id, 698 render_process_id,
640 request_id)); 699 request_id));
641 700
642 ChromeThread::PostTask( 701 ChromeThread::PostTask(
643 ChromeThread::FILE, FROM_HERE, 702 ChromeThread::FILE,
703 FROM_HERE,
644 NewRunnableMethod( 704 NewRunnableMethod(
645 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 705 file_manager_, &DownloadFileManager::CancelDownload, download_id));
646 } 706 }
647 707
648 void DownloadManager::PauseDownload(int32 download_id, bool pause) { 708 void DownloadManager::PauseDownload(int32 download_id, bool pause) {
649 DownloadMap::iterator it = in_progress_.find(download_id); 709 DownloadMap::iterator it = in_progress_.find(download_id);
650 if (it == in_progress_.end()) 710 if (it == in_progress_.end())
651 return; 711 return;
652 712
653 DownloadItem* download = it->second; 713 DownloadItem* download = it->second;
654 if (pause == download->is_paused()) 714 if (pause == download->is_paused())
655 return; 715 return;
656 716
657 ChromeThread::PostTask( 717 ChromeThread::PostTask(
658 ChromeThread::IO, FROM_HERE, 718 ChromeThread::IO,
719 FROM_HERE,
659 NewRunnableMethod(this, 720 NewRunnableMethod(this,
660 &DownloadManager::PauseDownloadRequest, 721 &DownloadManager::PauseDownloadRequest,
661 g_browser_process->resource_dispatcher_host(), 722 g_browser_process->resource_dispatcher_host(),
662 download->render_process_id(), 723 download->render_process_id(),
663 download->request_id(), 724 download->request_id(),
664 pause)); 725 pause));
665 } 726 }
666 727
728 void DownloadManager::RestartDownload(int32 download_id) {
729 // Handle the case of clicking 'Resume' in the download shelf.
730 DownloadMap::iterator it = in_progress_.find(download_id);
731 if (it == in_progress_.end())
732 return;
733
734 DownloadItem* download = it->second;
735 if (!download->IsInterruptedDownload())
736 return;
737
738 // Restart the download.
739 // |info| is cleaned up in ResourceDispatcherHost::RestartRequestAsync().
740 DownloadCreateInfo* info = new DownloadCreateInfo(
741 download->full_path(),
742 download->url(),
743 download->start_time(),
744 download->received_bytes(),
745 download->total_bytes(),
746 DownloadItem::IN_PROGRESS, // Don't want this to show INTERRUPTED.
747 -1);
748 info->referrer_url = download->referrer_url();
749
750 // Inform the ResourceDispatcherHost that we're restarting the download.
751 ChromeThread::PostTask(
752 ChromeThread::IO,
753 FROM_HERE,
754 NewRunnableMethod(this,
755 &DownloadManager::RestartDownloadRequest,
756 g_browser_process->resource_dispatcher_host(),
757 download->render_process_id(),
758 download->request_id(),
759 info));
760 }
761
667 void DownloadManager::UpdateAppIcon() { 762 void DownloadManager::UpdateAppIcon() {
668 int64 total_bytes = 0; 763 int64 total_bytes = 0;
669 int64 received_bytes = 0; 764 int64 received_bytes = 0;
670 int download_count = 0; 765 int download_count = 0;
671 bool progress_known = true; 766 bool progress_known = true;
672 767
673 for (DownloadMap::iterator i = in_progress_.begin(); 768 for (DownloadMap::iterator i = in_progress_.begin();
674 i != in_progress_.end(); 769 i != in_progress_.end();
675 ++i) { 770 ++i) {
676 ++download_count; 771 ++download_count;
(...skipping 24 matching lines...) Expand all
701 } 796 }
702 797
703 void DownloadManager::PauseDownloadRequest(ResourceDispatcherHost* rdh, 798 void DownloadManager::PauseDownloadRequest(ResourceDispatcherHost* rdh,
704 int render_process_id, 799 int render_process_id,
705 int request_id, 800 int request_id,
706 bool pause) { 801 bool pause) {
707 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); 802 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
708 rdh->PauseRequest(render_process_id, request_id, pause); 803 rdh->PauseRequest(render_process_id, request_id, pause);
709 } 804 }
710 805
806 void DownloadManager::RestartDownloadRequest(ResourceDispatcherHost* rdh,
807 int render_process_id,
808 int request_id,
809 DownloadCreateInfo* info) {
810 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
811 rdh->RestartRequest(render_process_id, request_id, info);
812 }
813
711 void DownloadManager::RemoveDownload(int64 download_handle) { 814 void DownloadManager::RemoveDownload(int64 download_handle) {
712 DownloadMap::iterator it = downloads_.find(download_handle); 815 DownloadMap::iterator it = downloads_.find(download_handle);
713 if (it == downloads_.end()) 816 if (it == downloads_.end())
714 return; 817 return;
715 818
716 // Make history update. 819 // Make history update.
717 DownloadItem* download = it->second; 820 DownloadItem* download = it->second;
718 download_history_->RemoveEntry(download); 821 download_history_->RemoveEntry(download);
719 822
720 // Remove from our tables and delete. 823 // Remove from our tables and delete.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(), 901 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(),
799 tab_contents); 902 tab_contents);
800 } 903 }
801 904
802 void DownloadManager::DownloadUrlToFile(const GURL& url, 905 void DownloadManager::DownloadUrlToFile(const GURL& url,
803 const GURL& referrer, 906 const GURL& referrer,
804 const std::string& referrer_charset, 907 const std::string& referrer_charset,
805 const DownloadSaveInfo& save_info, 908 const DownloadSaveInfo& save_info,
806 TabContents* tab_contents) { 909 TabContents* tab_contents) {
807 DCHECK(tab_contents); 910 DCHECK(tab_contents);
808 ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, 911 ChromeThread::PostTask(
912 ChromeThread::IO,
913 FROM_HERE,
809 NewRunnableFunction(&download_util::DownloadUrl, 914 NewRunnableFunction(&download_util::DownloadUrl,
810 url, 915 url,
811 referrer, 916 referrer,
812 referrer_charset, 917 referrer_charset,
813 save_info, 918 save_info,
814 g_browser_process->resource_dispatcher_host(), 919 g_browser_process->resource_dispatcher_host(),
815 tab_contents->GetRenderProcessHost()->id(), 920 tab_contents->GetRenderProcessHost()->id(),
816 tab_contents->render_view_host()->routing_id(), 921 tab_contents->render_view_host()->routing_id(),
817 request_context_getter_)); 922 request_context_getter_));
818 } 923 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state()); 966 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state());
862 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED); 967 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED);
863 download->UpdateObservers(); 968 download->UpdateObservers();
864 969
865 // If the download is not complete, nothing to do. The required 970 // If the download is not complete, nothing to do. The required
866 // post-processing will be performed when it does complete. 971 // post-processing will be performed when it does complete.
867 if (download->state() != DownloadItem::COMPLETE) 972 if (download->state() != DownloadItem::COMPLETE)
868 return; 973 return;
869 974
870 ChromeThread::PostTask( 975 ChromeThread::PostTask(
871 ChromeThread::FILE, FROM_HERE, 976 ChromeThread::FILE,
977 FROM_HERE,
872 NewRunnableMethod( 978 NewRunnableMethod(
873 this, &DownloadManager::ProceedWithFinishedDangerousDownload, 979 this, &DownloadManager::ProceedWithFinishedDangerousDownload,
874 download->db_handle(), download->full_path(), 980 download->db_handle(), download->full_path(),
875 download->original_name())); 981 download->original_name()));
876 } 982 }
877 983
878 // Operations posted to us from the history service ---------------------------- 984 // Operations posted to us from the history service ----------------------------
879 985
880 // The history service has retrieved all download entries. 'entries' contains 986 // The history service has retrieved all download entries. 'entries' contains
881 // 'DownloadCreateInfo's in sorted order (by ascending start_time). 987 // 'DownloadCreateInfo's in sorted order (by ascending start_time).
(...skipping 10 matching lines...) Expand all
892 // Once the new DownloadItem's creation info has been committed to the history 998 // Once the new DownloadItem's creation info has been committed to the history
893 // service, we associate the DownloadItem with the db handle, update our 999 // service, we associate the DownloadItem with the db handle, update our
894 // 'downloads_' map and inform observers. 1000 // 'downloads_' map and inform observers.
895 void DownloadManager::OnCreateDownloadEntryComplete(DownloadCreateInfo info, 1001 void DownloadManager::OnCreateDownloadEntryComplete(DownloadCreateInfo info,
896 int64 db_handle) { 1002 int64 db_handle) {
897 DownloadMap::iterator it = in_progress_.find(info.download_id); 1003 DownloadMap::iterator it = in_progress_.find(info.download_id);
898 DCHECK(it != in_progress_.end()); 1004 DCHECK(it != in_progress_.end());
899 1005
900 DownloadItem* download = it->second; 1006 DownloadItem* download = it->second;
901 1007
902 // It's not immediately obvious, but HistoryBackend::CreateDownload() can 1008 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
903 // call this function with an invalid |db_handle|. For instance, this can 1009 // We're reusing the download.
904 // happen when the history database is offline. We cannot have multiple 1010 } else {
905 // DownloadItems with the same invalid db_handle, so we need to assign a 1011 // It's not immediately obvious, but HistoryBackend::CreateDownload() can
906 // unique |db_handle| here. 1012 // call this function with an invalid |db_handle|. For instance, this can
907 if (db_handle == DownloadHistory::kUninitializedHandle) 1013 // happen when the history database is offline. We cannot have multiple
908 db_handle = download_history_->GetNextFakeDbHandle(); 1014 // DownloadItems with the same invalid db_handle, so we need to assign a
1015 // unique |db_handle| here.
1016 if (db_handle == DownloadHistory::kUninitializedHandle)
1017 db_handle = download_history_->GetNextFakeDbHandle();
909 1018
910 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); 1019 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
911 download->set_db_handle(db_handle); 1020 download->set_db_handle(db_handle);
912 1021
913 // Insert into our full map. 1022 // Insert into our full map.
914 DCHECK(downloads_.find(download->db_handle()) == downloads_.end()); 1023 DCHECK(downloads_.find(download->db_handle()) == downloads_.end());
915 downloads_[download->db_handle()] = download; 1024 downloads_[download->db_handle()] = download;
1025 }
916 1026
917 // Show in the appropropriate browser UI. 1027 // Show in the appropropriate browser UI.
918 ShowDownloadInBrowser(info, download); 1028 ShowDownloadInBrowser(info, download);
919 1029
920 // Inform interested objects about the new download. 1030 // Inform interested objects about the new download.
921 NotifyModelChanged(); 1031 NotifyModelChanged();
922 1032
923 // If this download has been completed before we've received the db handle, 1033 // If this download has been completed before we've received the db handle,
924 // post one final message to the history service so that it can be properly 1034 // post one final message to the history service so that it can be properly
925 // in sync with the DownloadItem's completion status, and also inform any 1035 // in sync with the DownloadItem's completion status, and also inform any
926 // observers so that they get more than just the start notification. 1036 // observers so that they get more than just the start notification.
927 if (download->state() != DownloadItem::IN_PROGRESS) { 1037 if (download->state() != DownloadItem::IN_PROGRESS) {
928 in_progress_.erase(it); 1038 if (!download->IsInterruptedDownload())
1039 in_progress_.erase(it);
929 download_history_->UpdateEntry(download); 1040 download_history_->UpdateEntry(download);
930 download->UpdateObservers(); 1041 download->UpdateObservers();
931 } 1042 }
932 1043
933 UpdateAppIcon(); 1044 UpdateAppIcon();
934 } 1045 }
935 1046
936 void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info, 1047 void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info,
937 DownloadItem* download) { 1048 DownloadItem* download) {
938 // The 'contents' may no longer exist if the user closed the tab before we 1049 // The 'contents' may no longer exist if the user closed the tab before we
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 observed_download_manager_->RemoveObserver(this); 1105 observed_download_manager_->RemoveObserver(this);
995 } 1106 }
996 1107
997 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { 1108 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() {
998 observing_download_manager_->NotifyModelChanged(); 1109 observing_download_manager_->NotifyModelChanged();
999 } 1110 }
1000 1111
1001 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1112 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1002 observed_download_manager_ = NULL; 1113 observed_download_manager_ = NULL;
1003 } 1114 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698