Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/i18n/case_conversion.h" | 9 #include "base/i18n/case_conversion.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 #include "grit/theme_resources.h" | 47 #include "grit/theme_resources.h" |
| 48 #include "net/base/mime_util.h" | 48 #include "net/base/mime_util.h" |
| 49 #include "net/base/net_util.h" | 49 #include "net/base/net_util.h" |
| 50 #include "ui/base/l10n/l10n_util.h" | 50 #include "ui/base/l10n/l10n_util.h" |
| 51 #include "ui/base/resource/resource_bundle.h" | 51 #include "ui/base/resource/resource_bundle.h" |
| 52 | 52 |
| 53 DownloadManager::DownloadManager(DownloadStatusUpdater* status_updater) | 53 DownloadManager::DownloadManager(DownloadStatusUpdater* status_updater) |
| 54 : shutdown_needed_(false), | 54 : shutdown_needed_(false), |
| 55 profile_(NULL), | 55 profile_(NULL), |
| 56 file_manager_(NULL), | 56 file_manager_(NULL), |
| 57 status_updater_(status_updater->AsWeakPtr()) { | 57 status_updater_(status_updater->AsWeakPtr()), |
| 58 next_save_page_id_(0) { | |
| 58 if (status_updater_) | 59 if (status_updater_) |
| 59 status_updater_->AddDelegate(this); | 60 status_updater_->AddDelegate(this); |
| 60 } | 61 } |
| 61 | 62 |
| 62 DownloadManager::~DownloadManager() { | 63 DownloadManager::~DownloadManager() { |
| 63 DCHECK(!shutdown_needed_); | 64 DCHECK(!shutdown_needed_); |
| 64 if (status_updater_) | 65 if (status_updater_) |
| 65 status_updater_->RemoveDelegate(this); | 66 status_updater_->RemoveDelegate(this); |
| 66 } | 67 } |
| 67 | 68 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 // anything left. | 116 // anything left. |
| 116 | 117 |
| 117 // Copy downloads_ to separate container so as not to set off checks | 118 // Copy downloads_ to separate container so as not to set off checks |
| 118 // in DownloadItem destruction. | 119 // in DownloadItem destruction. |
| 119 DownloadSet downloads_to_delete; | 120 DownloadSet downloads_to_delete; |
| 120 downloads_to_delete.swap(downloads_); | 121 downloads_to_delete.swap(downloads_); |
| 121 | 122 |
| 122 in_progress_.clear(); | 123 in_progress_.clear(); |
| 123 active_downloads_.clear(); | 124 active_downloads_.clear(); |
| 124 history_downloads_.clear(); | 125 history_downloads_.clear(); |
| 125 #if !defined(NDEBUG) | |
| 126 save_page_as_downloads_.clear(); | |
| 127 #endif | |
| 128 STLDeleteElements(&downloads_to_delete); | 126 STLDeleteElements(&downloads_to_delete); |
| 129 | 127 |
| 128 DCHECK(save_page_downloads_.empty()); | |
| 129 | |
| 130 file_manager_ = NULL; | 130 file_manager_ = NULL; |
| 131 | 131 |
| 132 // Make sure the save as dialog doesn't notify us back if we're gone before | 132 // Make sure the save as dialog doesn't notify us back if we're gone before |
| 133 // it returns. | 133 // it returns. |
| 134 if (select_file_dialog_.get()) | 134 if (select_file_dialog_.get()) |
| 135 select_file_dialog_->ListenerDestroyed(); | 135 select_file_dialog_->ListenerDestroyed(); |
| 136 | 136 |
| 137 download_history_.reset(); | 137 download_history_.reset(); |
| 138 download_prefs_.reset(); | 138 download_prefs_.reset(); |
| 139 | 139 |
| 140 shutdown_needed_ = false; | 140 shutdown_needed_ = false; |
| 141 } | 141 } |
| 142 | 142 |
| 143 void DownloadManager::GetTemporaryDownloads( | 143 void DownloadManager::GetTemporaryDownloads( |
| 144 const FilePath& dir_path, std::vector<DownloadItem*>* result) { | 144 const FilePath& dir_path, DownloadVec* result) { |
| 145 DCHECK(result); | 145 DCHECK(result); |
| 146 | 146 |
| 147 for (DownloadMap::iterator it = history_downloads_.begin(); | 147 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 148 it != history_downloads_.end(); ++it) { | 148 it != history_downloads_.end(); ++it) { |
| 149 if (it->second->is_temporary() && | 149 if (it->second->is_temporary() && |
| 150 it->second->full_path().DirName() == dir_path) | 150 it->second->full_path().DirName() == dir_path) |
| 151 result->push_back(it->second); | 151 result->push_back(it->second); |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 void DownloadManager::GetAllDownloads( | 155 void DownloadManager::GetAllDownloads( |
| 156 const FilePath& dir_path, std::vector<DownloadItem*>* result) { | 156 const FilePath& dir_path, DownloadVec* result) { |
| 157 DCHECK(result); | 157 DCHECK(result); |
| 158 | 158 |
| 159 for (DownloadMap::iterator it = history_downloads_.begin(); | 159 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 160 it != history_downloads_.end(); ++it) { | 160 it != history_downloads_.end(); ++it) { |
| 161 if (!it->second->is_temporary() && | 161 if (!it->second->is_temporary() && |
| 162 (dir_path.empty() || it->second->full_path().DirName() == dir_path)) | 162 (dir_path.empty() || it->second->full_path().DirName() == dir_path)) |
| 163 result->push_back(it->second); | 163 result->push_back(it->second); |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 | 166 |
| 167 void DownloadManager::GetCurrentDownloads( | 167 void DownloadManager::GetCurrentDownloads( |
| 168 const FilePath& dir_path, std::vector<DownloadItem*>* result) { | 168 const FilePath& dir_path, DownloadVec* result) { |
| 169 DCHECK(result); | 169 DCHECK(result); |
| 170 | 170 |
| 171 for (DownloadMap::iterator it = history_downloads_.begin(); | 171 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 172 it != history_downloads_.end(); ++it) { | 172 it != history_downloads_.end(); ++it) { |
| 173 DownloadItem* item =it->second; | 173 DownloadItem* item =it->second; |
| 174 // Skip temporary items. | 174 // Skip temporary items. |
| 175 if (item->is_temporary()) | 175 if (item->is_temporary()) |
| 176 continue; | 176 continue; |
| 177 // Skip items that have all their data, and are OK to save. | 177 // Skip items that have all their data, and are OK to save. |
| 178 if (!item->IsPartialDownload() && | 178 if (!item->IsPartialDownload() && |
| 179 (item->safety_state() != DownloadItem::DANGEROUS)) | 179 (item->safety_state() != DownloadItem::DANGEROUS)) |
| 180 continue; | 180 continue; |
| 181 // Skip items that don't match |dir_path|. | 181 // Skip items that don't match |dir_path|. |
| 182 // If |dir_path| is empty, all remaining items match. | 182 // If |dir_path| is empty, all remaining items match. |
| 183 if (!dir_path.empty() && (it->second->full_path().DirName() != dir_path)) | 183 if (!dir_path.empty() && (it->second->full_path().DirName() != dir_path)) |
| 184 continue; | 184 continue; |
| 185 | 185 |
| 186 result->push_back(item); | 186 result->push_back(item); |
| 187 } | 187 } |
| 188 | 188 |
| 189 // If we have a parent profile, let it add its downloads to the results. | 189 // If we have a parent profile, let it add its downloads to the results. |
| 190 Profile* original_profile = profile_->GetOriginalProfile(); | 190 Profile* original_profile = profile_->GetOriginalProfile(); |
| 191 if (original_profile != profile_) | 191 if (original_profile != profile_) |
| 192 original_profile->GetDownloadManager()->GetCurrentDownloads(dir_path, | 192 original_profile->GetDownloadManager()->GetCurrentDownloads(dir_path, |
| 193 result); | 193 result); |
| 194 } | 194 } |
| 195 | 195 |
| 196 void DownloadManager::SearchDownloads(const string16& query, | 196 void DownloadManager::SearchDownloads(const string16& query, |
| 197 std::vector<DownloadItem*>* result) { | 197 DownloadVec* result) { |
| 198 DCHECK(result); | 198 DCHECK(result); |
| 199 | 199 |
| 200 string16 query_lower(base::i18n::ToLower(query)); | 200 string16 query_lower(base::i18n::ToLower(query)); |
| 201 | 201 |
| 202 for (DownloadMap::iterator it = history_downloads_.begin(); | 202 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 203 it != history_downloads_.end(); ++it) { | 203 it != history_downloads_.end(); ++it) { |
| 204 DownloadItem* download_item = it->second; | 204 DownloadItem* download_item = it->second; |
| 205 | 205 |
| 206 if (download_item->is_temporary() || download_item->is_extension_install()) | 206 if (download_item->is_temporary() || download_item->is_extension_install()) |
| 207 continue; | 207 continue; |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 892 BrowserThread::FILE, FROM_HERE, | 892 BrowserThread::FILE, FROM_HERE, |
| 893 NewRunnableMethod( | 893 NewRunnableMethod( |
| 894 file_manager_, &DownloadFileManager::CancelDownload, download_id)); | 894 file_manager_, &DownloadFileManager::CancelDownload, download_id)); |
| 895 } | 895 } |
| 896 | 896 |
| 897 void DownloadManager::UpdateAppIcon() { | 897 void DownloadManager::UpdateAppIcon() { |
| 898 if (status_updater_) | 898 if (status_updater_) |
| 899 status_updater_->Update(); | 899 status_updater_->Update(); |
| 900 } | 900 } |
| 901 | 901 |
| 902 int DownloadManager::RemoveDownloadItems(const DownloadVec& pending_deletes) { | |
| 903 if (pending_deletes.empty()) | |
| 904 return 0; | |
| 905 | |
| 906 // Delete from internal maps. | |
| 907 for (size_t i = 0; i < pending_deletes.size(); ++i) { | |
| 908 DownloadItem* download = pending_deletes[i]; | |
| 909 DCHECK(download); | |
| 910 history_downloads_.erase(download->db_handle()); | |
| 911 save_page_downloads_.erase(download->id()); | |
| 912 downloads_.erase(download); | |
| 913 } | |
| 914 | |
| 915 // Tell observers to refresh their views. | |
| 916 NotifyModelChanged(); | |
| 917 | |
| 918 // Delete the download items themselves. | |
| 919 const int num_deleted = static_cast<int>(pending_deletes.size()); | |
|
Paweł Hajdan Jr.
2011/07/27 16:53:51
nit: "const int" inside a method is generally an o
achuithb
2011/07/28 00:45:58
Do you feel strongly about this? I like const auto
| |
| 920 STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end()); | |
| 921 return num_deleted; | |
| 922 } | |
| 923 | |
| 902 void DownloadManager::RemoveDownload(int64 download_handle) { | 924 void DownloadManager::RemoveDownload(int64 download_handle) { |
| 903 DownloadMap::iterator it = history_downloads_.find(download_handle); | 925 DownloadMap::iterator it = history_downloads_.find(download_handle); |
| 904 if (it == history_downloads_.end()) | 926 if (it == history_downloads_.end()) |
| 905 return; | 927 return; |
| 906 | 928 |
| 907 // Make history update. | 929 // Make history update. |
| 908 DownloadItem* download = it->second; | 930 DownloadItem* download = it->second; |
| 909 download_history_->RemoveEntry(download); | 931 download_history_->RemoveEntry(download); |
| 910 | 932 |
| 911 // Remove from our tables and delete. | 933 // Remove from our tables and delete. |
| 912 history_downloads_.erase(it); | 934 int downloads_count = RemoveDownloadItems(DownloadVec(1, download)); |
| 913 int downloads_count = downloads_.erase(download); | |
| 914 DCHECK_EQ(1, downloads_count); | 935 DCHECK_EQ(1, downloads_count); |
| 915 | |
| 916 // Tell observers to refresh their views. | |
| 917 NotifyModelChanged(); | |
| 918 | |
| 919 delete download; | |
| 920 } | 936 } |
| 921 | 937 |
| 922 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, | 938 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, |
| 923 const base::Time remove_end) { | 939 const base::Time remove_end) { |
| 924 download_history_->RemoveEntriesBetween(remove_begin, remove_end); | 940 download_history_->RemoveEntriesBetween(remove_begin, remove_end); |
| 925 | 941 |
| 926 // All downloads visible to the user will be in the history, | 942 // All downloads visible to the user will be in the history, |
| 927 // so scan that map. | 943 // so scan that map. |
| 928 DownloadMap::iterator it = history_downloads_.begin(); | 944 DownloadVec pending_deletes; |
| 929 std::vector<DownloadItem*> pending_deletes; | 945 for (DownloadMap::iterator it = history_downloads_.begin(); |
| 930 while (it != history_downloads_.end()) { | 946 it != history_downloads_.end(); |
| 947 ++it) { | |
| 931 DownloadItem* download = it->second; | 948 DownloadItem* download = it->second; |
| 932 if (download->start_time() >= remove_begin && | 949 if (download->start_time() >= remove_begin && |
| 933 (remove_end.is_null() || download->start_time() < remove_end) && | 950 (remove_end.is_null() || download->start_time() < remove_end) && |
| 934 (download->IsComplete() || | 951 (download->IsComplete() || |
| 935 download->IsCancelled() || | 952 download->IsCancelled() || |
| 936 download->IsInterrupted())) { | 953 download->IsInterrupted())) { |
| 937 AssertQueueStateConsistent(download); | 954 AssertQueueStateConsistent(download); |
| 938 | 955 |
| 939 // Remove from the map and move to the next in the list. | |
| 940 history_downloads_.erase(it++); | |
| 941 | |
| 942 // Also remove it from any completed dangerous downloads. | |
| 943 pending_deletes.push_back(download); | 956 pending_deletes.push_back(download); |
| 944 | |
| 945 continue; | |
| 946 } | 957 } |
| 947 | |
| 948 ++it; | |
| 949 } | 958 } |
| 950 | 959 return RemoveDownloadItems(pending_deletes); |
| 951 // If we aren't deleting anything, we're done. | |
| 952 if (pending_deletes.empty()) | |
| 953 return 0; | |
| 954 | |
| 955 // Remove the chosen downloads from the main owning container. | |
| 956 for (std::vector<DownloadItem*>::iterator it = pending_deletes.begin(); | |
| 957 it != pending_deletes.end(); it++) { | |
| 958 downloads_.erase(*it); | |
| 959 } | |
| 960 | |
| 961 // Tell observers to refresh their views. | |
| 962 NotifyModelChanged(); | |
| 963 | |
| 964 // Delete the download items themselves. | |
| 965 int num_deleted = static_cast<int>(pending_deletes.size()); | |
| 966 | |
| 967 STLDeleteContainerPointers(pending_deletes.begin(), pending_deletes.end()); | |
| 968 pending_deletes.clear(); | |
| 969 | |
| 970 return num_deleted; | |
| 971 } | 960 } |
| 972 | 961 |
| 973 int DownloadManager::RemoveDownloads(const base::Time remove_begin) { | 962 int DownloadManager::RemoveDownloads(const base::Time remove_begin) { |
| 974 return RemoveDownloadsBetween(remove_begin, base::Time()); | 963 return RemoveDownloadsBetween(remove_begin, base::Time()); |
| 975 } | 964 } |
| 976 | 965 |
| 977 int DownloadManager::RemoveAllDownloads() { | 966 int DownloadManager::RemoveAllDownloads() { |
| 978 if (this != profile_->GetOriginalProfile()->GetDownloadManager()) { | 967 if (this != profile_->GetOriginalProfile()->GetDownloadManager()) { |
| 979 // This is an incognito downloader. Clear All should clear main download | 968 // This is an incognito downloader. Clear All should clear main download |
| 980 // manager as well. | 969 // manager as well. |
| 981 profile_->GetOriginalProfile()->GetDownloadManager()->RemoveAllDownloads(); | 970 profile_->GetOriginalProfile()->GetDownloadManager()->RemoveAllDownloads(); |
| 982 } | 971 } |
| 983 // The null times make the date range unbounded. | 972 // The null times make the date range unbounded. |
| 984 return RemoveDownloadsBetween(base::Time(), base::Time()); | 973 return RemoveDownloadsBetween(base::Time(), base::Time()); |
| 985 } | 974 } |
| 986 | 975 |
| 987 void DownloadManager::SavePageAsDownloadStarted(DownloadItem* download) { | |
| 988 #if !defined(NDEBUG) | |
| 989 save_page_as_downloads_.insert(download); | |
| 990 #endif | |
| 991 downloads_.insert(download); | |
| 992 // Add to history and notify observers. | |
| 993 AddDownloadItemToHistory(download, DownloadHistory::kUninitializedHandle); | |
| 994 NotifyModelChanged(); | |
| 995 } | |
| 996 | |
| 997 // Initiate a download of a specific URL. We send the request to the | 976 // Initiate a download of a specific URL. We send the request to the |
| 998 // ResourceDispatcherHost, and let it send us responses like a regular | 977 // ResourceDispatcherHost, and let it send us responses like a regular |
| 999 // download. | 978 // download. |
| 1000 void DownloadManager::DownloadUrl(const GURL& url, | 979 void DownloadManager::DownloadUrl(const GURL& url, |
| 1001 const GURL& referrer, | 980 const GURL& referrer, |
| 1002 const std::string& referrer_charset, | 981 const std::string& referrer_charset, |
| 1003 TabContents* tab_contents) { | 982 TabContents* tab_contents) { |
| 1004 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(), | 983 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(), |
| 1005 tab_contents); | 984 tab_contents); |
| 1006 } | 985 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1180 | 1159 |
| 1181 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 | 1160 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 |
| 1182 // is fixed. | 1161 // is fixed. |
| 1183 CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle); | 1162 CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle); |
| 1184 | 1163 |
| 1185 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); | 1164 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); |
| 1186 download->set_db_handle(db_handle); | 1165 download->set_db_handle(db_handle); |
| 1187 | 1166 |
| 1188 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); | 1167 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); |
| 1189 history_downloads_[download->db_handle()] = download; | 1168 history_downloads_[download->db_handle()] = download; |
| 1169 | |
| 1170 // Show in the appropriate browser UI. | |
| 1171 // This includes buttons to save or cancel, for a dangerous download. | |
| 1172 ShowDownloadInBrowser(download); | |
| 1173 | |
| 1174 // Inform interested objects about the new download. | |
| 1175 NotifyModelChanged(); | |
| 1190 } | 1176 } |
| 1191 | 1177 |
| 1192 // Once the new DownloadItem's creation info has been committed to the history | 1178 // Once the new DownloadItem's creation info has been committed to the history |
| 1193 // service, we associate the DownloadItem with the db handle, update our | 1179 // service, we associate the DownloadItem with the db handle, update our |
| 1194 // 'history_downloads_' map and inform observers. | 1180 // 'history_downloads_' map and inform observers. |
| 1195 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, | 1181 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, |
| 1196 int64 db_handle) { | 1182 int64 db_handle) { |
| 1197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1198 DownloadItem* download = GetActiveDownloadItem(download_id); | 1184 DownloadItem* download = GetActiveDownloadItem(download_id); |
| 1199 if (!download) | 1185 if (!download) |
| 1200 return; | 1186 return; |
| 1201 | 1187 |
| 1202 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle | 1188 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle |
| 1203 << " download_id = " << download_id | 1189 << " download_id = " << download_id |
| 1204 << " download = " << download->DebugString(true); | 1190 << " download = " << download->DebugString(true); |
| 1205 | 1191 |
| 1206 AddDownloadItemToHistory(download, db_handle); | 1192 AddDownloadItemToHistory(download, db_handle); |
| 1207 | 1193 |
| 1208 // Show in the appropriate browser UI. | |
| 1209 // This includes buttons to save or cancel, for a dangerous download. | |
| 1210 ShowDownloadInBrowser(download); | |
| 1211 | |
| 1212 // Inform interested objects about the new download. | |
| 1213 NotifyModelChanged(); | |
| 1214 | |
| 1215 // If the download is still in progress, try to complete it. | 1194 // If the download is still in progress, try to complete it. |
| 1216 // | 1195 // |
| 1217 // Otherwise, download has been cancelled or interrupted before we've | 1196 // Otherwise, download has been cancelled or interrupted before we've |
| 1218 // received the DB handle. We post one final message to the history | 1197 // received the DB handle. We post one final message to the history |
| 1219 // service so that it can be properly in sync with the DownloadItem's | 1198 // service so that it can be properly in sync with the DownloadItem's |
| 1220 // completion status, and also inform any observers so that they get | 1199 // completion status, and also inform any observers so that they get |
| 1221 // more than just the start notification. | 1200 // more than just the start notification. |
| 1222 if (download->IsInProgress()) { | 1201 if (download->IsInProgress()) { |
| 1223 MaybeCompleteDownload(download); | 1202 MaybeCompleteDownload(download); |
| 1224 } else { | 1203 } else { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1278 DownloadItem* download = active_downloads_[download_id]; | 1257 DownloadItem* download = active_downloads_[download_id]; |
| 1279 DCHECK(download != NULL); | 1258 DCHECK(download != NULL); |
| 1280 return download; | 1259 return download; |
| 1281 } | 1260 } |
| 1282 | 1261 |
| 1283 // Confirm that everything in all maps is also in |downloads_|, and that | 1262 // Confirm that everything in all maps is also in |downloads_|, and that |
| 1284 // everything in |downloads_| is also in some other map. | 1263 // everything in |downloads_| is also in some other map. |
| 1285 void DownloadManager::AssertContainersConsistent() const { | 1264 void DownloadManager::AssertContainersConsistent() const { |
| 1286 #if !defined(NDEBUG) | 1265 #if !defined(NDEBUG) |
| 1287 // Turn everything into sets. | 1266 // Turn everything into sets. |
| 1288 DownloadSet active_set, history_set; | 1267 const DownloadMap* input_maps[] = {&active_downloads_, |
| 1289 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_}; | 1268 &history_downloads_, |
| 1290 DownloadSet* local_sets[] = {&active_set, &history_set}; | 1269 &save_page_downloads_}; |
| 1291 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); | 1270 DownloadSet active_set, history_set, save_page_set; |
| 1271 DownloadSet* all_sets[] = {&active_set, &history_set, &save_page_set}; | |
| 1272 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(all_sets)); | |
| 1292 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { | 1273 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { |
| 1293 for (DownloadMap::const_iterator it = input_maps[i]->begin(); | 1274 for (DownloadMap::const_iterator it = input_maps[i]->begin(); |
| 1294 it != input_maps[i]->end(); it++) { | 1275 it != input_maps[i]->end(); ++it) { |
| 1295 local_sets[i]->insert(&*it->second); | 1276 all_sets[i]->insert(&*it->second); |
| 1296 } | 1277 } |
| 1297 } | 1278 } |
| 1298 | 1279 |
| 1299 // Check if each set is fully present in downloads, and create a union. | 1280 // Check if each set is fully present in downloads, and create a union. |
| 1300 const DownloadSet* all_sets[] = {&active_set, &history_set, | |
| 1301 &save_page_as_downloads_}; | |
| 1302 DownloadSet downloads_union; | 1281 DownloadSet downloads_union; |
| 1303 for (int i = 0; i < static_cast<int>(ARRAYSIZE_UNSAFE(all_sets)); i++) { | 1282 for (int i = 0; i < static_cast<int>(ARRAYSIZE_UNSAFE(all_sets)); i++) { |
| 1304 DownloadSet remainder; | 1283 DownloadSet remainder; |
| 1305 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); | 1284 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); |
| 1306 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), | 1285 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), |
| 1307 downloads_.begin(), downloads_.end(), | 1286 downloads_.begin(), downloads_.end(), |
| 1308 insert_it); | 1287 insert_it); |
| 1309 DCHECK(remainder.empty()); | 1288 DCHECK(remainder.empty()); |
| 1310 std::insert_iterator<DownloadSet> | 1289 std::insert_iterator<DownloadSet> |
| 1311 insert_union(downloads_union, downloads_union.end()); | 1290 insert_union(downloads_union, downloads_union.end()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1346 observed_download_manager_->RemoveObserver(this); | 1325 observed_download_manager_->RemoveObserver(this); |
| 1347 } | 1326 } |
| 1348 | 1327 |
| 1349 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { | 1328 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { |
| 1350 observing_download_manager_->NotifyModelChanged(); | 1329 observing_download_manager_->NotifyModelChanged(); |
| 1351 } | 1330 } |
| 1352 | 1331 |
| 1353 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { | 1332 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { |
| 1354 observed_download_manager_ = NULL; | 1333 observed_download_manager_ = NULL; |
| 1355 } | 1334 } |
| 1335 | |
| 1336 void DownloadManager::SavePageDownloadStarted(DownloadItem* download) { | |
| 1337 DCHECK(!ContainsKey(save_page_downloads_, download->id())); | |
| 1338 downloads_.insert(download); | |
| 1339 save_page_downloads_[download->id()] = download; | |
| 1340 | |
| 1341 // Add this entry to the history service. | |
| 1342 // Additionally, the UI is notified in the callback. | |
| 1343 download_history_->AddEntry(download, | |
| 1344 NewCallback(this, &DownloadManager::OnSavePageDownloadEntryAdded)); | |
| 1345 } | |
| 1346 | |
| 1347 void DownloadManager::OnSavePageDownloadEntryAdded(int32 download_id, | |
| 1348 int64 db_handle) { | |
| 1349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1350 | |
| 1351 DownloadMap::const_iterator it = save_page_downloads_.find(download_id); | |
| 1352 // This can happen if the download manager is shutting down and all maps | |
| 1353 // have been cleared. | |
| 1354 if (it == save_page_downloads_.end()) | |
| 1355 return; | |
| 1356 | |
| 1357 DownloadItem* download = it->second; | |
| 1358 DCHECK(download); | |
|
Paweł Hajdan Jr.
2011/07/27 16:53:51
nit: Better use the idiom below:
if (!download) {
achuithb
2011/07/28 00:45:58
Done.
| |
| 1359 if (!download) | |
| 1360 return; | |
| 1361 | |
| 1362 AddDownloadItemToHistory(download, db_handle); | |
| 1363 | |
| 1364 // Finalize this download if it finished before the history callback. | |
| 1365 if (!download->IsInProgress()) | |
| 1366 SavePageDownloadFinished(download); | |
| 1367 } | |
| 1368 | |
| 1369 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) { | |
| 1370 if (download->db_handle() != DownloadHistory::kUninitializedHandle) { | |
| 1371 download_history_->UpdateEntry(download); | |
| 1372 DCHECK(ContainsKey(save_page_downloads_, download->id())); | |
| 1373 save_page_downloads_.erase(download->id()); | |
| 1374 } | |
| 1375 } | |
| 1376 | |
| 1377 int32 DownloadManager::GetNextSavePageId() { | |
| 1378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1379 return next_save_page_id_++; | |
| 1380 } | |
| 1381 | |
| OLD | NEW |