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

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

Issue 7277073: Support for adding save page download items into downloads history. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 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 | Annotate | Revision Log
OLDNEW
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
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
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
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 if (it == history_downloads_.end()) 905 if (it == history_downloads_.end())
906 return; 906 return;
907 907
908 // Make history update. 908 // Make history update.
909 DownloadItem* download = it->second; 909 DownloadItem* download = it->second;
910 download_history_->RemoveEntry(download); 910 download_history_->RemoveEntry(download);
911 911
912 // Remove from our tables and delete. 912 // Remove from our tables and delete.
913 history_downloads_.erase(it); 913 history_downloads_.erase(it);
914 int downloads_count = downloads_.erase(download); 914 int downloads_count = downloads_.erase(download);
915 DCHECK_EQ(1, downloads_count); 915 DCHECK_EQ(1, downloads_count);
Randy Smith (Not in Mondays) 2011/07/25 18:59:31 We need to remove the download from save_page_down
achuithb 2011/07/27 01:04:57 I took the liberty of pulling out all the code tha
Randy Smith (Not in Mondays) 2011/07/27 21:08:35 I think this was a good idea that probably proacti
916 916
917 // Tell observers to refresh their views. 917 // Tell observers to refresh their views.
918 NotifyModelChanged(); 918 NotifyModelChanged();
919 919
920 delete download; 920 delete download;
921 } 921 }
922 922
923 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin, 923 int DownloadManager::RemoveDownloadsBetween(const base::Time remove_begin,
924 const base::Time remove_end) { 924 const base::Time remove_end) {
925 download_history_->RemoveEntriesBetween(remove_begin, remove_end); 925 download_history_->RemoveEntriesBetween(remove_begin, remove_end);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 int DownloadManager::RemoveAllDownloads() { 978 int DownloadManager::RemoveAllDownloads() {
979 if (this != profile_->GetOriginalProfile()->GetDownloadManager()) { 979 if (this != profile_->GetOriginalProfile()->GetDownloadManager()) {
980 // This is an incognito downloader. Clear All should clear main download 980 // This is an incognito downloader. Clear All should clear main download
981 // manager as well. 981 // manager as well.
982 profile_->GetOriginalProfile()->GetDownloadManager()->RemoveAllDownloads(); 982 profile_->GetOriginalProfile()->GetDownloadManager()->RemoveAllDownloads();
983 } 983 }
984 // The null times make the date range unbounded. 984 // The null times make the date range unbounded.
985 return RemoveDownloadsBetween(base::Time(), base::Time()); 985 return RemoveDownloadsBetween(base::Time(), base::Time());
986 } 986 }
987 987
988 void DownloadManager::SavePageAsDownloadStarted(DownloadItem* download) {
989 #if !defined(NDEBUG)
990 save_page_as_downloads_.insert(download);
991 #endif
992 downloads_.insert(download);
993 // Add to history and notify observers.
994 AddDownloadItemToHistory(download, DownloadHistory::kUninitializedHandle);
995 NotifyModelChanged();
996 }
997
998 // Initiate a download of a specific URL. We send the request to the 988 // Initiate a download of a specific URL. We send the request to the
999 // ResourceDispatcherHost, and let it send us responses like a regular 989 // ResourceDispatcherHost, and let it send us responses like a regular
1000 // download. 990 // download.
1001 void DownloadManager::DownloadUrl(const GURL& url, 991 void DownloadManager::DownloadUrl(const GURL& url,
1002 const GURL& referrer, 992 const GURL& referrer,
1003 const std::string& referrer_charset, 993 const std::string& referrer_charset,
1004 TabContents* tab_contents) { 994 TabContents* tab_contents) {
1005 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(), 995 DownloadUrlToFile(url, referrer, referrer_charset, DownloadSaveInfo(),
1006 tab_contents); 996 tab_contents);
1007 } 997 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 1180
1191 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508 1181 // TODO(rdsmith): Convert to DCHECK() when http://crbug.com/84508
1192 // is fixed. 1182 // is fixed.
1193 CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle); 1183 CHECK_NE(DownloadHistory::kUninitializedHandle, db_handle);
1194 1184
1195 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle); 1185 DCHECK(download->db_handle() == DownloadHistory::kUninitializedHandle);
1196 download->set_db_handle(db_handle); 1186 download->set_db_handle(db_handle);
1197 1187
1198 DCHECK(!ContainsKey(history_downloads_, download->db_handle())); 1188 DCHECK(!ContainsKey(history_downloads_, download->db_handle()));
1199 history_downloads_[download->db_handle()] = download; 1189 history_downloads_[download->db_handle()] = download;
1190
1191 // Show in the appropriate browser UI.
1192 // This includes buttons to save or cancel, for a dangerous download.
1193 ShowDownloadInBrowser(download);
1194
1195 // Inform interested objects about the new download.
1196 NotifyModelChanged();
1200 } 1197 }
1201 1198
1202 // Once the new DownloadItem's creation info has been committed to the history 1199 // Once the new DownloadItem's creation info has been committed to the history
1203 // service, we associate the DownloadItem with the db handle, update our 1200 // service, we associate the DownloadItem with the db handle, update our
1204 // 'history_downloads_' map and inform observers. 1201 // 'history_downloads_' map and inform observers.
1205 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id, 1202 void DownloadManager::OnCreateDownloadEntryComplete(int32 download_id,
1206 int64 db_handle) { 1203 int64 db_handle) {
1207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1208 DownloadItem* download = GetActiveDownloadItem(download_id); 1205 DownloadItem* download = GetActiveDownloadItem(download_id);
1209 if (!download) 1206 if (!download)
1210 return; 1207 return;
1211 1208
1212 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle 1209 VLOG(20) << __FUNCTION__ << "()" << " db_handle = " << db_handle
1213 << " download_id = " << download_id 1210 << " download_id = " << download_id
1214 << " download = " << download->DebugString(true); 1211 << " download = " << download->DebugString(true);
1215 1212
1216 AddDownloadItemToHistory(download, db_handle); 1213 AddDownloadItemToHistory(download, db_handle);
1217 1214
1218 // Show in the appropriate browser UI.
1219 // This includes buttons to save or cancel, for a dangerous download.
1220 ShowDownloadInBrowser(download);
1221
1222 // Inform interested objects about the new download.
1223 NotifyModelChanged();
1224
1225 // If the download is still in progress, try to complete it. 1215 // If the download is still in progress, try to complete it.
1226 // 1216 //
1227 // Otherwise, download has been cancelled or interrupted before we've 1217 // Otherwise, download has been cancelled or interrupted before we've
1228 // received the DB handle. We post one final message to the history 1218 // received the DB handle. We post one final message to the history
1229 // service so that it can be properly in sync with the DownloadItem's 1219 // service so that it can be properly in sync with the DownloadItem's
1230 // completion status, and also inform any observers so that they get 1220 // completion status, and also inform any observers so that they get
1231 // more than just the start notification. 1221 // more than just the start notification.
1232 if (download->IsInProgress()) { 1222 if (download->IsInProgress()) {
1233 MaybeCompleteDownload(download); 1223 MaybeCompleteDownload(download);
1234 } else { 1224 } else {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 DownloadItem* download = active_downloads_[download_id]; 1278 DownloadItem* download = active_downloads_[download_id];
1289 DCHECK(download != NULL); 1279 DCHECK(download != NULL);
1290 return download; 1280 return download;
1291 } 1281 }
1292 1282
1293 // Confirm that everything in all maps is also in |downloads_|, and that 1283 // Confirm that everything in all maps is also in |downloads_|, and that
1294 // everything in |downloads_| is also in some other map. 1284 // everything in |downloads_| is also in some other map.
1295 void DownloadManager::AssertContainersConsistent() const { 1285 void DownloadManager::AssertContainersConsistent() const {
1296 #if !defined(NDEBUG) 1286 #if !defined(NDEBUG)
1297 // Turn everything into sets. 1287 // Turn everything into sets.
1298 DownloadSet active_set, history_set; 1288 const DownloadMap* input_maps[] = {&active_downloads_,
1299 const DownloadMap* input_maps[] = {&active_downloads_, &history_downloads_}; 1289 &history_downloads_,
1300 DownloadSet* local_sets[] = {&active_set, &history_set}; 1290 &save_page_downloads_};
1301 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(local_sets)); 1291 DownloadSet active_set, history_set, save_page_set;
1292 DownloadSet* all_sets[] = {&active_set, &history_set, &save_page_set};
1293 DCHECK_EQ(ARRAYSIZE_UNSAFE(input_maps), ARRAYSIZE_UNSAFE(all_sets));
1302 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) { 1294 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(input_maps); i++) {
1303 for (DownloadMap::const_iterator it = input_maps[i]->begin(); 1295 for (DownloadMap::const_iterator it = input_maps[i]->begin();
1304 it != input_maps[i]->end(); it++) { 1296 it != input_maps[i]->end(); ++it) {
1305 local_sets[i]->insert(&*it->second); 1297 all_sets[i]->insert(&*it->second);
1306 } 1298 }
1307 } 1299 }
1308 1300
1309 // Check if each set is fully present in downloads, and create a union. 1301 // Check if each set is fully present in downloads, and create a union.
1310 const DownloadSet* all_sets[] = {&active_set, &history_set,
1311 &save_page_as_downloads_};
1312 DownloadSet downloads_union; 1302 DownloadSet downloads_union;
1313 for (int i = 0; i < static_cast<int>(ARRAYSIZE_UNSAFE(all_sets)); i++) { 1303 for (int i = 0; i < static_cast<int>(ARRAYSIZE_UNSAFE(all_sets)); i++) {
1314 DownloadSet remainder; 1304 DownloadSet remainder;
1315 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin()); 1305 std::insert_iterator<DownloadSet> insert_it(remainder, remainder.begin());
1316 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(), 1306 std::set_difference(all_sets[i]->begin(), all_sets[i]->end(),
1317 downloads_.begin(), downloads_.end(), 1307 downloads_.begin(), downloads_.end(),
1318 insert_it); 1308 insert_it);
1319 DCHECK(remainder.empty()); 1309 DCHECK(remainder.empty());
1320 std::insert_iterator<DownloadSet> 1310 std::insert_iterator<DownloadSet>
1321 insert_union(downloads_union, downloads_union.end()); 1311 insert_union(downloads_union, downloads_union.end());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 observed_download_manager_->RemoveObserver(this); 1346 observed_download_manager_->RemoveObserver(this);
1357 } 1347 }
1358 1348
1359 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { 1349 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() {
1360 observing_download_manager_->NotifyModelChanged(); 1350 observing_download_manager_->NotifyModelChanged();
1361 } 1351 }
1362 1352
1363 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1353 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1364 observed_download_manager_ = NULL; 1354 observed_download_manager_ = NULL;
1365 } 1355 }
1356
1357 void DownloadManager::SavePageDownloadStarted(DownloadItem* download) {
1358 DCHECK(!ContainsKey(save_page_downloads_, download->id()));
1359 downloads_.insert(download);
1360 save_page_downloads_[download->id()] = download;
1361
1362 // Add this entry to the history service.
1363 // Additionally, the UI is notified in the callback.
1364 download_history_->AddEntry(download,
1365 NewCallback(this, &DownloadManager::OnSavePageDownloadEntryAdded));
1366 }
1367
1368 void DownloadManager::OnSavePageDownloadEntryAdded(int32 download_id,
1369 int64 db_handle) {
1370 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1371
1372 DownloadMap::const_iterator it = save_page_downloads_.find(download_id);
1373 // This can happen if SavePageDownloadFinished happens before the history
1374 // callback. In that case, the download is stuck in pending downloads
1375 // state and never finishes. This will be fixed with the integration of
1376 // SavePackage into DownloadManager.
Randy Smith (Not in Mondays) 2011/07/25 18:59:31 This comment is no longer correct and should be up
achuithb 2011/07/27 01:04:57 I updated the comment. This can now only happen if
1377 if (it == save_page_downloads_.end())
1378 return;
1379
1380 DownloadItem* download = it->second;
1381 DCHECK(download);
1382 if (!download)
1383 return;
1384
1385 AddDownloadItemToHistory(download, db_handle);
1386
1387 // Finalize this download if it terminated before the history callback.
1388 if (!download->IsInProgress())
1389 SavePageDownloadFinished(download);
1390 }
1391
1392 void DownloadManager::SavePageDownloadFinished(DownloadItem* download) {
1393 if (download->db_handle() != DownloadHistory::kUninitializedHandle) {
1394 download_history_->UpdateEntry(download);
1395 DCHECK(ContainsKey(save_page_downloads_, download->id()));
1396 save_page_downloads_.erase(download->id());
1397 }
1398 }
1399
1400 int32 DownloadManager::GetNextSavePageId() {
1401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1402 return next_save_page_id_++;
1403 }
1404
OLDNEW
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/save_page_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698