summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/download/download_manager.cc21
-rw-r--r--chrome/browser/download/download_manager.h5
-rw-r--r--chrome/browser/history/download_database.cc10
-rw-r--r--chrome/browser/history/download_database.h6
-rw-r--r--chrome/browser/history/history.cc7
-rw-r--r--chrome/browser/history/history.h4
-rw-r--r--chrome/browser/history/history_backend.cc9
-rw-r--r--chrome/browser/history/history_backend.h1
-rw-r--r--chrome/browser/history/history_unittest.cc16
9 files changed, 79 insertions, 0 deletions
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index 5b804d7..6d79b58 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -537,6 +537,10 @@ bool DownloadManager::Init(Profile* profile) {
// information about new downloads while in that mode.
QueryHistoryForDownloads();
+ // Cleans up entries only when called for the first time. Subsequent calls are
+ // a no op.
+ CleanUpInProgressHistoryEntries();
+
ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host();
if (!rdh) {
NOTREACHED();
@@ -588,6 +592,18 @@ void DownloadManager::QueryHistoryForDownloads() {
}
}
+void DownloadManager::CleanUpInProgressHistoryEntries() {
+ static bool already_cleaned_up = false;
+
+ if (!already_cleaned_up) {
+ HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
+ if (hs) {
+ hs->CleanUpInProgressEntries();
+ already_cleaned_up = true;
+ }
+ }
+}
+
// We have received a message from DownloadFileManager about a new download. We
// create a download item and store it in our download map, and inform the
// history system of a new download. Since this method can be called while the
@@ -1221,6 +1237,11 @@ int DownloadManager::RemoveDownloads(const base::Time remove_begin) {
}
int DownloadManager::RemoveAllDownloads() {
+ if (this != profile_->GetOriginalProfile()->GetDownloadManager()) {
+ // This is an incognito downloader. Clear All should clear main download
+ // manager as well.
+ profile_->GetOriginalProfile()->GetDownloadManager()->RemoveAllDownloads();
+ }
// The null times make the date range unbounded.
return RemoveDownloadsBetween(base::Time(), base::Time());
}
diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h
index c77d480..0707711 100644
--- a/chrome/browser/download/download_manager.h
+++ b/chrome/browser/download/download_manager.h
@@ -395,6 +395,11 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>,
// Schedule a query of the history service to retrieve all downloads.
void QueryHistoryForDownloads();
+ // Cleans up IN_PROGRESS history entries as these entries are corrupt because
+ // of the sudden exit. Changes them to CANCELED. Executed only when called
+ // first time, subsequent calls a no op.
+ void CleanUpInProgressHistoryEntries();
+
// Notifications sent from the download thread to the UI thread
void StartDownload(DownloadCreateInfo* info);
void UpdateDownload(int32 download_id, int64 size);
diff --git a/chrome/browser/history/download_database.cc b/chrome/browser/history/download_database.cc
index 8bf4a95..ea0649d 100644
--- a/chrome/browser/history/download_database.cc
+++ b/chrome/browser/history/download_database.cc
@@ -135,6 +135,16 @@ bool DownloadDatabase::UpdateDownloadPath(const std::wstring& path,
return statement.Run();
}
+bool DownloadDatabase::CleanUpInProgressEntries() {
+ sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
+ "UPDATE downloads SET state=? WHERE state=?"));
+ if (!statement)
+ return false;
+ statement.BindInt(0, DownloadItem::CANCELLED);
+ statement.BindInt(1, DownloadItem::IN_PROGRESS);
+ return statement.Run();
+}
+
int64 DownloadDatabase::CreateDownload(const DownloadCreateInfo& info) {
sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE,
"INSERT INTO downloads "
diff --git a/chrome/browser/history/download_database.h b/chrome/browser/history/download_database.h
index 1efb6d4..8ba2e7a 100644
--- a/chrome/browser/history/download_database.h
+++ b/chrome/browser/history/download_database.h
@@ -31,6 +31,12 @@ class DownloadDatabase {
// Update the path of one download. Returns true if successful.
bool UpdateDownloadPath(const std::wstring& path, DownloadID db_handle);
+ // Fixes state of the download entries. Sometimes entries with IN_PROGRESS
+ // state are not updated during browser shutdown (particularly when crashing).
+ // On the next start such entries are considered canceled. This functions
+ // fixes such entries.
+ bool CleanUpInProgressEntries();
+
// Create a new database entry for one download and return its primary db id.
int64 CreateDownload(const DownloadCreateInfo& info);
diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc
index fe85e5f..0e685748 100644
--- a/chrome/browser/history/history.cc
+++ b/chrome/browser/history/history.cc
@@ -488,6 +488,13 @@ HistoryService::Handle HistoryService::QueryDownloads(
new history::DownloadQueryRequest(callback));
}
+// Changes all IN_PROGRESS in the database entries to CANCELED.
+// IN_PROGRESS entries are the corrupted entries, not updated by next function
+// because of the crash or some other extremal exit.
+void HistoryService::CleanUpInProgressEntries() {
+ ScheduleAndForget(PRIORITY_NORMAL, &HistoryBackend::CleanUpInProgressEntries);
+}
+
// Handle updates for a particular download. This is a 'fire and forget'
// operation, so we don't need to be called back.
void HistoryService::UpdateDownload(int64 received_bytes,
diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h
index 2326f8b..3507817 100644
--- a/chrome/browser/history/history.h
+++ b/chrome/browser/history/history.h
@@ -406,6 +406,10 @@ class HistoryService : public CancelableRequestProvider,
Handle QueryDownloads(CancelableRequestConsumerBase* consumer,
DownloadQueryCallback* callback);
+ // Begins a request to clean up entries that has been corrupted (because of
+ // the crash, for example).
+ void CleanUpInProgressEntries();
+
// Called to update the history service about the current state of a download.
// This is a 'fire and forget' query, so just pass the relevant state info to
// the database with no need for a callback.
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index 4be006a..caaec96 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -1040,6 +1040,15 @@ void HistoryBackend::QueryDownloads(
request->ForwardResult(DownloadQueryRequest::TupleType(&request->value));
}
+// Clean up entries that has been corrupted (because of the crash, for example).
+void HistoryBackend::CleanUpInProgressEntries() {
+ if (db_.get()) {
+ // If some "in progress" entries were not updated when Chrome exited, they
+ // need to be cleaned up.
+ db_->CleanUpInProgressEntries();
+ }
+}
+
// Update a particular download entry.
void HistoryBackend::UpdateDownload(int64 received_bytes,
int32 state,
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index 7289b5a..4b37f29 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -201,6 +201,7 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>,
// Downloads -----------------------------------------------------------------
void QueryDownloads(scoped_refptr<DownloadQueryRequest> request);
+ void CleanUpInProgressEntries();
void UpdateDownload(int64 received_bytes, int32 state, int64 db_handle);
void UpdateDownloadPath(const std::wstring& path, int64 db_handle);
void CreateDownload(scoped_refptr<DownloadCreateRequest> request,
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc
index 00e9154..c0b65b3 100644
--- a/chrome/browser/history/history_unittest.cc
+++ b/chrome/browser/history/history_unittest.cc
@@ -382,6 +382,22 @@ TEST_F(HistoryTest, ClearBrowsingData_Downloads) {
db_->RemoveDownloadsBetween(Time(), Time());
db_->QueryDownloads(&downloads);
EXPECT_EQ(0U, downloads.size());
+
+ // Check removal of downloads stuck in IN_PROGRESS state.
+ EXPECT_NE(0, AddDownload(DownloadItem::COMPLETE, month_ago));
+ EXPECT_NE(0, AddDownload(DownloadItem::IN_PROGRESS, month_ago));
+ db_->QueryDownloads(&downloads);
+ EXPECT_EQ(2U, downloads.size());
+ db_->RemoveDownloadsBetween(Time(), Time());
+ db_->QueryDownloads(&downloads);
+ // IN_PROGRESS download should remain. It it indicated as "Canceled"
+ EXPECT_EQ(1U, downloads.size());
+ db_->CleanUpInProgressEntries();
+ db_->QueryDownloads(&downloads);
+ EXPECT_EQ(1U, downloads.size());
+ db_->RemoveDownloadsBetween(Time(), Time());
+ db_->QueryDownloads(&downloads);
+ EXPECT_EQ(0U, downloads.size());
}
TEST_F(HistoryTest, AddPage) {