OLD | NEW |
---|---|
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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 // At this point, all dangerous downloads have had their files removed | 116 // At this point, all dangerous downloads have had their files removed |
117 // and all in progress downloads have been cancelled. We can now delete | 117 // and all in progress downloads have been cancelled. We can now delete |
118 // anything left. | 118 // anything left. |
119 STLDeleteElements(&downloads_); | 119 STLDeleteElements(&downloads_); |
120 | 120 |
121 // And clear all non-owning containers. | 121 // And clear all non-owning containers. |
122 in_progress_.clear(); | 122 in_progress_.clear(); |
123 active_downloads_.clear(); | |
123 #if !defined(NDEBUG) | 124 #if !defined(NDEBUG) |
124 save_page_as_downloads_.clear(); | 125 save_page_as_downloads_.clear(); |
125 #endif | 126 #endif |
126 | 127 |
127 file_manager_ = NULL; | 128 file_manager_ = NULL; |
128 | 129 |
129 // Make sure the save as dialog doesn't notify us back if we're gone before | 130 // Make sure the save as dialog doesn't notify us back if we're gone before |
130 // it returns. | 131 // it returns. |
131 if (select_file_dialog_.get()) | 132 if (select_file_dialog_.get()) |
132 select_file_dialog_->ListenerDestroyed(); | 133 select_file_dialog_->ListenerDestroyed(); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 AttachDownloadItem(info, info->suggested_path); | 421 AttachDownloadItem(info, info->suggested_path); |
421 } | 422 } |
422 } | 423 } |
423 | 424 |
424 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { | 425 void DownloadManager::CreateDownloadItem(DownloadCreateInfo* info) { |
425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
426 | 427 |
427 DownloadItem* download = new DownloadItem(this, *info, | 428 DownloadItem* download = new DownloadItem(this, *info, |
428 profile_->IsOffTheRecord()); | 429 profile_->IsOffTheRecord()); |
429 DCHECK(!ContainsKey(in_progress_, info->download_id)); | 430 DCHECK(!ContainsKey(in_progress_, info->download_id)); |
431 DCHECK(!ContainsKey(active_downloads_, info->download_id)); | |
430 downloads_.insert(download); | 432 downloads_.insert(download); |
433 active_downloads_[info->download_id] = download; | |
431 } | 434 } |
432 | 435 |
433 void DownloadManager::AttachDownloadItem(DownloadCreateInfo* info, | 436 void DownloadManager::AttachDownloadItem(DownloadCreateInfo* info, |
434 const FilePath& target_path) { | 437 const FilePath& target_path) { |
435 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 438 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
436 | 439 |
437 scoped_ptr<DownloadCreateInfo> infop(info); | 440 scoped_ptr<DownloadCreateInfo> infop(info); |
438 info->path = target_path; | 441 info->path = target_path; |
439 | 442 |
440 // NOTE(ahendrickson) We will be adding a new map |active_downloads_|, into | 443 // NOTE(ahendrickson) Eventually |active_downloads_| will replace |
441 // which we will be adding the download as soon as it's created. This will | 444 // |in_progress_|, but we don't want to change the semantics yet. |
442 // make this loop unnecessary. | |
443 // Eventually |active_downloads_| will replace |in_progress_|, but we don't | |
444 // want to change the semantics yet. | |
445 DCHECK(!ContainsKey(in_progress_, info->download_id)); | 445 DCHECK(!ContainsKey(in_progress_, info->download_id)); |
446 DownloadItem* download = NULL; | 446 DCHECK(ContainsKey(active_downloads_, info->download_id)); |
447 for (std::set<DownloadItem*>::iterator i = downloads_.begin(); | 447 DownloadItem* download = active_downloads_[info->download_id]; |
448 i != downloads_.end(); ++i) { | |
449 DownloadItem* item = (*i); | |
450 if (item && (item->id() == info->download_id)) { | |
451 download = item; | |
452 break; | |
453 } | |
454 } | |
455 DCHECK(download != NULL); | 448 DCHECK(download != NULL); |
449 DCHECK(downloads_.find(download) != downloads_.end()); | |
450 | |
456 download->SetFileCheckResults(info->path, | 451 download->SetFileCheckResults(info->path, |
457 info->is_dangerous, | 452 info->is_dangerous, |
458 info->path_uniquifier, | 453 info->path_uniquifier, |
459 info->prompt_user_for_save_location, | 454 info->prompt_user_for_save_location, |
460 info->is_extension_install, | 455 info->is_extension_install, |
461 info->original_name); | 456 info->original_name); |
462 in_progress_[info->download_id] = download; | 457 in_progress_[info->download_id] = download; |
463 | 458 |
464 bool download_finished = ContainsKey(pending_finished_downloads_, | 459 bool download_finished = ContainsKey(pending_finished_downloads_, |
465 info->download_id); | 460 info->download_id); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 pending_finished_downloads_[info->download_id]); | 494 pending_finished_downloads_[info->download_id]); |
500 } | 495 } |
501 | 496 |
502 download_history_->AddEntry(*info, download, | 497 download_history_->AddEntry(*info, download, |
503 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); | 498 NewCallback(this, &DownloadManager::OnCreateDownloadEntryComplete)); |
504 | 499 |
505 UpdateAppIcon(); | 500 UpdateAppIcon(); |
506 } | 501 } |
507 | 502 |
508 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { | 503 void DownloadManager::UpdateDownload(int32 download_id, int64 size) { |
509 DownloadMap::iterator it = in_progress_.find(download_id); | 504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
510 if (it != in_progress_.end()) { | 505 DownloadMap::iterator it = active_downloads_.find(download_id); |
506 if (it != active_downloads_.end()) { | |
511 DownloadItem* download = it->second; | 507 DownloadItem* download = it->second; |
512 download->Update(size); | 508 download->Update(size); |
513 download_history_->UpdateEntry(download); | 509 download_history_->UpdateEntry(download); |
514 } | 510 } |
515 UpdateAppIcon(); | 511 UpdateAppIcon(); |
516 } | 512 } |
517 | 513 |
518 void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) { | 514 void DownloadManager::OnAllDataSaved(int32 download_id, int64 size) { |
519 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 515 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
520 << " size = " << size; | 516 << " size = " << size; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
573 NewRunnableMethod( | 569 NewRunnableMethod( |
574 this, &DownloadManager::ProceedWithFinishedDangerousDownload, | 570 this, &DownloadManager::ProceedWithFinishedDangerousDownload, |
575 download->db_handle(), | 571 download->db_handle(), |
576 download->full_path(), download->target_name())); | 572 download->full_path(), download->target_name())); |
577 return; | 573 return; |
578 } | 574 } |
579 | 575 |
580 download->OnSafeDownloadFinished(file_manager_); | 576 download->OnSafeDownloadFinished(file_manager_); |
581 } | 577 } |
582 | 578 |
579 void DownloadManager::OnDownloadFileCompleted(int32 download_id) { | |
580 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
581 | |
582 active_downloads_.erase(download_id); | |
583 } | |
584 | |
583 void DownloadManager::DownloadRenamedToFinalName(int download_id, | 585 void DownloadManager::DownloadRenamedToFinalName(int download_id, |
584 const FilePath& full_path) { | 586 const FilePath& full_path) { |
585 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 587 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
586 << " full_path = \"" << full_path.value() << "\""; | 588 << " full_path = \"" << full_path.value() << "\""; |
587 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 589 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
588 DownloadItem* item = GetDownloadItem(download_id); | 590 DownloadItem* item = GetDownloadItem(download_id); |
589 if (!item) | 591 if (!item) |
590 return; | 592 return; |
591 item->OnDownloadRenamedToFinalName(full_path); | 593 item->OnDownloadRenamedToFinalName(full_path); |
592 } | 594 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
642 // name when calling GetFileNameToReportUser(). | 644 // name when calling GetFileNameToReportUser(). |
643 download->set_path_uniquifier(new_path_uniquifier); | 645 download->set_path_uniquifier(new_path_uniquifier); |
644 RenameDownload(download, new_path); | 646 RenameDownload(download, new_path); |
645 } | 647 } |
646 | 648 |
647 // Continue the download finished sequence. | 649 // Continue the download finished sequence. |
648 download->Finished(); | 650 download->Finished(); |
649 } | 651 } |
650 | 652 |
651 void DownloadManager::DownloadCancelled(int32 download_id) { | 653 void DownloadManager::DownloadCancelled(int32 download_id) { |
654 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
652 DownloadMap::iterator it = in_progress_.find(download_id); | 655 DownloadMap::iterator it = in_progress_.find(download_id); |
653 if (it == in_progress_.end()) | 656 if (it == in_progress_.end()) |
654 return; | 657 return; |
655 DownloadItem* download = it->second; | 658 DownloadItem* download = it->second; |
656 | 659 |
657 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id | 660 VLOG(20) << __FUNCTION__ << "()" << " download_id = " << download_id |
658 << " download = " << download->DebugString(true); | 661 << " download = " << download->DebugString(true); |
659 | 662 |
660 // Clean up will happen when the history system create callback runs if we | 663 // Clean up will happen when the history system create callback runs if we |
661 // don't have a valid db_handle yet. | 664 // don't have a valid db_handle yet. |
662 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | 665 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { |
663 in_progress_.erase(it); | 666 in_progress_.erase(it); |
667 active_downloads_.erase(download_id); | |
664 download_history_->UpdateEntry(download); | 668 download_history_->UpdateEntry(download); |
665 } | 669 } |
666 | 670 |
667 DownloadCancelledInternal(download_id, | 671 DownloadCancelledInternal(download_id, |
668 download->render_process_id(), | 672 download->render_process_id(), |
669 download->request_id()); | 673 download->request_id()); |
670 UpdateAppIcon(); | 674 UpdateAppIcon(); |
671 } | 675 } |
672 | 676 |
673 void DownloadManager::DownloadCancelledInternal(int download_id, | 677 void DownloadManager::DownloadCancelledInternal(int download_id, |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
952 } | 956 } |
953 NotifyModelChanged(); | 957 NotifyModelChanged(); |
954 } | 958 } |
955 | 959 |
956 // Once the new DownloadItem's creation info has been committed to the history | 960 // Once the new DownloadItem's creation info has been committed to the history |
957 // service, we associate the DownloadItem with the db handle, update our | 961 // service, we associate the DownloadItem with the db handle, update our |
958 // 'history_downloads_' map and inform observers. | 962 // 'history_downloads_' map and inform observers. |
959 void DownloadManager::OnCreateDownloadEntryComplete( | 963 void DownloadManager::OnCreateDownloadEntryComplete( |
960 DownloadCreateInfo info, | 964 DownloadCreateInfo info, |
961 int64 db_handle) { | 965 int64 db_handle) { |
966 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
962 DownloadMap::iterator it = in_progress_.find(info.download_id); | 967 DownloadMap::iterator it = in_progress_.find(info.download_id); |
963 DCHECK(it != in_progress_.end()); | 968 DCHECK(it != in_progress_.end()); |
964 | 969 |
965 DownloadItem* download = it->second; | 970 DownloadItem* download = it->second; |
966 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle | 971 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
967 << " download_id = " << info.download_id | 972 << " download_id = " << info.download_id |
968 << " download = " << download->DebugString(true); | 973 << " download = " << download->DebugString(true); |
969 | 974 |
970 // It's not immediately obvious, but HistoryBackend::CreateDownload() can | 975 // It's not immediately obvious, but HistoryBackend::CreateDownload() can |
971 // call this function with an invalid |db_handle|. For instance, this can | 976 // call this function with an invalid |db_handle|. For instance, this can |
972 // happen when the history database is offline. We cannot have multiple | 977 // happen when the history database is offline. We cannot have multiple |
973 // DownloadItems with the same invalid db_handle, so we need to assign a | 978 // DownloadItems with the same invalid db_handle, so we need to assign a |
974 // unique |db_handle| here. | 979 // unique |db_handle| here. |
975 if (db_handle == DownloadHistory::kUninitializedHandle) | 980 if (db_handle == DownloadHistory::kUninitializedHandle) |
976 db_handle = download_history_->GetNextFakeDbHandle(); | 981 db_handle = download_history_->GetNextFakeDbHandle(); |
977 | 982 |
978 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); | 983 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); |
979 download->set_db_handle(db_handle); | 984 download->set_db_handle(db_handle); |
980 | 985 |
981 // Insert into our full map. | 986 // Insert into our full map. |
982 DCHECK(history_downloads_.find(download->db_handle()) == | 987 DCHECK(history_downloads_.find(download->db_handle()) == |
983 history_downloads_.end()); | 988 history_downloads_.end()); |
984 history_downloads_[download->db_handle()] = download; | 989 history_downloads_[download->db_handle()] = download; |
985 | 990 |
986 // Show in the appropropriate browser UI. | 991 // Show in the appropriate browser UI. |
987 ShowDownloadInBrowser(info, download); | 992 ShowDownloadInBrowser(info, download); |
988 | 993 |
989 // Inform interested objects about the new download. | 994 // Inform interested objects about the new download. |
990 NotifyModelChanged(); | 995 NotifyModelChanged(); |
991 | 996 |
992 // If this download has been completed before we've received the db handle, | 997 // If this download has been completed before we've received the db handle, |
993 // post one final message to the history service so that it can be properly | 998 // post one final message to the history service so that it can be properly |
994 // in sync with the DownloadItem's completion status, and also inform any | 999 // in sync with the DownloadItem's completion status, and also inform any |
995 // observers so that they get more than just the start notification. | 1000 // observers so that they get more than just the start notification. |
996 if (download->state() != DownloadItem::IN_PROGRESS) { | 1001 if (download->state() != DownloadItem::IN_PROGRESS) { |
997 in_progress_.erase(it); | 1002 in_progress_.erase(it); |
1003 // TODO(ahendrickson) -- Fix this when we have a proper final state to | |
1004 // check for. | |
Randy Smith (Not in Mondays)
2011/01/04 21:05:35
I'd like a slightly more descriptive comment. Bas
ahendrickson
2011/01/05 00:32:46
Done.
| |
1005 active_downloads_.erase(info.download_id); | |
998 download_history_->UpdateEntry(download); | 1006 download_history_->UpdateEntry(download); |
999 download->UpdateObservers(); | 1007 download->UpdateObservers(); |
1000 } | 1008 } |
1001 | 1009 |
1002 UpdateAppIcon(); | 1010 UpdateAppIcon(); |
1003 } | 1011 } |
1004 | 1012 |
1005 void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info, | 1013 void DownloadManager::ShowDownloadInBrowser(const DownloadCreateInfo& info, |
1006 DownloadItem* download) { | 1014 DownloadItem* download) { |
1007 // The 'contents' may no longer exist if the user closed the tab before we | 1015 // The 'contents' may no longer exist if the user closed the tab before we |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1041 } | 1049 } |
1042 return NULL; | 1050 return NULL; |
1043 } | 1051 } |
1044 | 1052 |
1045 // Confirm that everything in all maps is also in |downloads_|, and that | 1053 // Confirm that everything in all maps is also in |downloads_|, and that |
1046 // everything in |downloads_| is also in some other map. | 1054 // everything in |downloads_| is also in some other map. |
1047 void DownloadManager::AssertContainersConsistent() const { | 1055 void DownloadManager::AssertContainersConsistent() const { |
1048 #if !defined(NDEBUG) | 1056 #if !defined(NDEBUG) |
1049 // Turn everything into sets. | 1057 // Turn everything into sets. |
1050 DownloadSet in_progress_set, history_set; | 1058 DownloadSet in_progress_set, history_set; |
1051 const DownloadMap* input_maps[] = {&in_progress_, &history_downloads_}; | 1059 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_}; |
1052 DownloadSet* local_sets[] = {&in_progress_set, &history_set}; | 1060 DownloadSet* local_sets[] = {&in_progress_set, &history_set}; |
1053 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); | 1061 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); |
1054 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { | 1062 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { |
1055 for (DownloadMap::const_iterator it = input_maps[i]->begin(); | 1063 for (DownloadMap::const_iterator it = input_maps[i]->begin(); |
1056 it != input_maps[i]->end(); it++) { | 1064 it != input_maps[i]->end(); it++) { |
1057 local_sets[i]->insert(&*it->second); | 1065 local_sets[i]->insert(&*it->second); |
1058 } | 1066 } |
1059 } | 1067 } |
1060 | 1068 |
1061 // Check if each set is fully present in downloads, and create a union. | 1069 // Check if each set is fully present in downloads, and create a union. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1108 observed_download_manager_->RemoveObserver(this); | 1116 observed_download_manager_->RemoveObserver(this); |
1109 } | 1117 } |
1110 | 1118 |
1111 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { | 1119 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { |
1112 observing_download_manager_->NotifyModelChanged(); | 1120 observing_download_manager_->NotifyModelChanged(); |
1113 } | 1121 } |
1114 | 1122 |
1115 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { | 1123 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { |
1116 observed_download_manager_ = NULL; | 1124 observed_download_manager_ = NULL; |
1117 } | 1125 } |
OLD | NEW |