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