Bug 230870 - Cross-Session resumable downloads (resume after quitting firefox). r=sdwilsh, a=mconnor

This commit is contained in:
edward.lee@engineering.uiuc.edu 2007-09-26 00:26:06 -07:00
Родитель 058eacad84
Коммит dbda8b5d76
2 изменённых файлов: 63 добавлений и 8 удалений

Просмотреть файл

@ -24,6 +24,7 @@
* Ben Goodger <ben@netscape.com> (Original Author) * Ben Goodger <ben@netscape.com> (Original Author)
* Shawn Wilsher <me@shawnwilsher.com> * Shawn Wilsher <me@shawnwilsher.com>
* Srirang G Doddihal <brahmana@doddihal.com> * Srirang G Doddihal <brahmana@doddihal.com>
* Edward Lee <edward.lee@engineering.uiuc.edu>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -129,16 +130,21 @@ nsDownloadManager::~nsDownloadManager()
} }
nsresult nsresult
nsDownloadManager::CancelAllDownloads() nsDownloadManager::RemoveAllDownloads()
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
for (PRInt32 i = mCurrentDownloads.Count() - 1; i >= 0; --i) { for (PRInt32 i = mCurrentDownloads.Count() - 1; i >= 0; --i) {
nsRefPtr<nsDownload> dl = mCurrentDownloads[0]; nsRefPtr<nsDownload> dl = mCurrentDownloads[0];
nsresult result = CancelDownload(dl->mID); nsresult result;
// We want to try the rest of them because they should be canceled if they if (dl->IsRealPaused())
// can be canceled. result = mCurrentDownloads.RemoveObject(dl);
if (NS_FAILED(result)) rv = result; else
result = CancelDownload(dl->mID);
// Track the failure, but don't miss out on other downloads
if (NS_FAILED(result))
rv = result;
} }
return rv; return rv;
@ -644,6 +650,33 @@ nsDownloadManager::RestoreDatabaseState()
return NS_OK; return NS_OK;
} }
nsresult
nsDownloadManager::RestoreActiveDownloads()
{
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id "
"FROM moz_downloads "
"WHERE state = ?1 "
"AND LENGTH(entityID) > 0"), getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindInt32Parameter(0, nsIDownloadManager::DOWNLOAD_PAUSED);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasResults;
while (NS_SUCCEEDED(stmt->ExecuteStep(&hasResults)) && hasResults) {
nsRefPtr<nsDownload> dl;
// Keep trying to add even if we fail one, but make sure to return failure.
// Additionally, be careful to not call anything that tries to change the
// database because we're iterating over a live statement.
if (NS_FAILED(GetDownloadFromDB(stmt->AsInt32(0), getter_AddRefs(dl))) ||
NS_FAILED(AddToCurrentDownloads(dl)))
rv = NS_ERROR_FAILURE;
}
return rv;
}
PRInt64 PRInt64
nsDownloadManager::AddDownloadToDB(const nsAString &aName, nsDownloadManager::AddDownloadToDB(const nsAString &aName,
const nsACString &aSource, const nsACString &aSource,
@ -718,6 +751,9 @@ nsDownloadManager::Init()
rv = RestoreDatabaseState(); rv = RestoreDatabaseState();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = RestoreActiveDownloads();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStringBundleService> bundleService = nsCOMPtr<nsIStringBundleService> bundleService =
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -1412,7 +1448,11 @@ nsDownloadManager::Observe(nsISupports *aSubject,
const char *aTopic, const char *aTopic,
const PRUnichar *aData) const PRUnichar *aData)
{ {
PRInt32 currDownloadCount = mCurrentDownloads.Count(); // Count active downloads that aren't real-paused
PRInt32 currDownloadCount = 0;
for (PRInt32 i = mCurrentDownloads.Count() - 1; i >= 0; --i)
if (!mCurrentDownloads[i]->IsRealPaused())
currDownloadCount++;
nsresult rv; nsresult rv;
if (strcmp(aTopic, "oncancel") == 0) { if (strcmp(aTopic, "oncancel") == 0) {
@ -1428,7 +1468,7 @@ nsDownloadManager::Observe(nsISupports *aSubject,
gStoppingDownloads = PR_TRUE; gStoppingDownloads = PR_TRUE;
if (currDownloadCount) if (currDownloadCount)
CancelAllDownloads(); (void)RemoveAllDownloads();
// Now that active downloads have been canceled, remove all downloads if // Now that active downloads have been canceled, remove all downloads if
// the user's retention policy specifies it. // the user's retention policy specifies it.

Просмотреть файл

@ -24,6 +24,7 @@
* Ben Goodger <ben@netscape.com> * Ben Goodger <ben@netscape.com>
* Shawn Wilsher <me@shawnwilsher.com> * Shawn Wilsher <me@shawnwilsher.com>
* Srirang G Doddihal <brahmana@doddihal.com> * Srirang G Doddihal <brahmana@doddihal.com>
* Edward Lee <edward.lee@engineering.uiuc.edu>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -99,6 +100,13 @@ protected:
nsresult CreateTable(); nsresult CreateTable();
nsresult ImportDownloadHistory(); nsresult ImportDownloadHistory();
nsresult RestoreDatabaseState(); nsresult RestoreDatabaseState();
/**
* Paused downloads that survive across sessions are considered active, so
* rebuild the list of these downloads.
*/
nsresult RestoreActiveDownloads();
nsresult GetDownloadFromDB(PRUint32 aID, nsDownload **retVal); nsresult GetDownloadFromDB(PRUint32 aID, nsDownload **retVal);
/** /**
@ -138,7 +146,14 @@ protected:
nsIDownload *aDownload); nsIDownload *aDownload);
nsDownload *FindDownload(PRUint32 aID); nsDownload *FindDownload(PRUint32 aID);
nsresult CancelAllDownloads();
/**
* Stop tracking the active downloads. Only use this when we're about to quit
* the download manager because we destroy our list of active downloads to
* break the dlmgr<->dl cycle. Active downloads that aren't real-paused will
* be canceled.
*/
nsresult RemoveAllDownloads();
/** /**
* Removes download from "current downloads". * Removes download from "current downloads".