Bug 251337 - Download manager history should have "aging" option, just like the browser history. r=sdwilsh, r=mano, r=bsmedberg, a1.9=damons

This commit is contained in:
edward.lee%engineering.uiuc.edu 2008-04-22 23:37:01 +00:00
Родитель 348b0bef75
Коммит 4f559235d3
9 изменённых файлов: 270 добавлений и 13 удалений

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

@ -52,6 +52,7 @@ DIRS += \
urlformatter \
contentprefs \
microformats \
places \
$(NULL)
# These component dirs are built only for XUL apps
@ -81,10 +82,6 @@ ifdef MOZ_HELP_VIEWER
DIRS += help
endif
ifdef MOZ_PLACES
DIRS += places
endif
ifdef NS_PRINTING
DIRS += printing
endif

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

@ -82,6 +82,7 @@ REQUIRES = \
feeds \
storage \
pipnss \
places \
$(NULL)
ifdef ALERTS_SERVICE

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

@ -68,6 +68,7 @@ REQUIRES = xpcom \
exthandler \
docshell \
toolkitcomps \
places \
$(NULL)
CPPSRCS = \

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

@ -61,6 +61,7 @@
#include "nsIPromptService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsTArray.h"
#include "nsVoidArray.h"
#include "nsEnumeratorUtils.h"
#include "nsIFileURL.h"
@ -109,7 +110,12 @@ static const PRInt64 gUpdateInterval = 400 * PR_USEC_PER_MSEC;
////////////////////////////////////////////////////////////////////////////////
//// nsDownloadManager
NS_IMPL_ISUPPORTS2(nsDownloadManager, nsIDownloadManager, nsIObserver)
NS_IMPL_ISUPPORTS3(
nsDownloadManager
, nsIDownloadManager
, nsINavHistoryObserver
, nsIObserver
)
nsDownloadManager *nsDownloadManager::gDownloadManagerService = nsnull;
@ -231,6 +237,37 @@ nsDownloadManager::RemoveAllDownloads()
return rv;
}
nsresult
nsDownloadManager::RemoveDownloadsForURI(nsIURI *aURI)
{
mozStorageStatementScoper scope(mGetIdsForURIStatement);
nsCAutoString source;
nsresult rv = aURI->GetSpec(source);
NS_ENSURE_SUCCESS(rv, rv);
rv = mGetIdsForURIStatement->BindUTF8StringParameter(0, source);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasMore = PR_FALSE;
nsAutoTArray<PRInt64, 4> downloads;
// Get all the downloads that match the provided URI
while (NS_SUCCEEDED(mGetIdsForURIStatement->ExecuteStep(&hasMore)) &&
hasMore) {
PRInt64 downloadId;
rv = mGetIdsForURIStatement->GetInt64(0, &downloadId);
NS_ENSURE_SUCCESS(rv, rv);
downloads.AppendElement(downloadId);
}
// Remove each download ignoring any failure so we reach other downloads
for (PRInt32 i = downloads.Length(); --i >= 0; )
(void)RemoveDownload(downloads[i]);
return NS_OK;
}
void // static
nsDownloadManager::ResumeOnWakeCallback(nsITimer *aTimer, void *aClosure)
{
@ -891,6 +928,12 @@ nsDownloadManager::Init()
"WHERE id = ?10"), getter_AddRefs(mUpdateDownloadStatement));
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id "
"FROM moz_downloads "
"WHERE source = ?1"), getter_AddRefs(mGetIdsForURIStatement));
NS_ENSURE_SUCCESS(rv, rv);
// Do things *after* initializing various download manager properties such as
// restoring downloads to a consistent state
rv = RestoreDatabaseState();
@ -899,6 +942,9 @@ nsDownloadManager::Init()
rv = RestoreActiveDownloads();
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to restore all active downloads");
nsCOMPtr<nsINavHistoryService> history =
do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
// The following three AddObserver calls must be the last lines in this function,
// because otherwise, this function may fail (and thus, this object would be not
// completely initialized), but the observerservice would still keep a reference
@ -914,6 +960,9 @@ nsDownloadManager::Init()
mObserverService->AddObserver(this, "sleep_notification", PR_FALSE);
mObserverService->AddObserver(this, "wake_notification", PR_FALSE);
if (history)
(void)history->AddObserver(this, PR_FALSE);
return NS_OK;
}
@ -1734,6 +1783,78 @@ nsDownloadManager::NotifyListenersOnStateChange(nsIWebProgress *aProgress,
aDownload);
}
////////////////////////////////////////////////////////////////////////////////
//// nsINavHistoryObserver
NS_IMETHODIMP
nsDownloadManager::OnBeginUpdateBatch()
{
// We already have a transaction, so don't make another
if (mHistoryTransaction)
return NS_OK;
// Start a transaction that commits when deleted
mHistoryTransaction = new mozStorageTransaction(mDBConn, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsDownloadManager::OnEndUpdateBatch()
{
if (mHistoryTransaction) {
// Delete the transaction and cause it to commit
delete mHistoryTransaction;
mHistoryTransaction = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsDownloadManager::OnVisit(nsIURI *aURI, PRInt64 aVisitID, PRTime aTime,
PRInt64 aSessionID, PRInt64 aReferringID,
PRUint32 aTransitionType, PRUint32 *aAdded)
{
return NS_OK;
}
NS_IMETHODIMP
nsDownloadManager::OnTitleChanged(nsIURI *aURI, const nsAString &aPageTitle)
{
return NS_OK;
}
NS_IMETHODIMP
nsDownloadManager::OnDeleteURI(nsIURI *aURI)
{
return RemoveDownloadsForURI(aURI);
}
NS_IMETHODIMP
nsDownloadManager::OnClearHistory()
{
return CleanUp();
}
NS_IMETHODIMP
nsDownloadManager::OnPageChanged(nsIURI *aURI, PRUint32 aWhat,
const nsAString &aValue)
{
return NS_OK;
}
NS_IMETHODIMP
nsDownloadManager::OnPageExpired(nsIURI *aURI, PRTime aVisitTime,
PRBool aWholeEntry)
{
// Don't bother removing downloads if there are still recent visits
if (!aWholeEntry)
return NS_OK;
return RemoveDownloadsForURI(aURI);
}
////////////////////////////////////////////////////////////////////////////////
//// nsIObserver

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

@ -61,9 +61,11 @@
#include "nsIMIMEInfo.h"
#include "mozIStorageConnection.h"
#include "mozIStorageStatement.h"
#include "mozStorageHelper.h"
#include "nsCOMArray.h"
#include "nsArrayEnumerator.h"
#include "nsAutoPtr.h"
#include "nsINavHistoryService.h"
#include "nsIObserverService.h"
#include "nsITimer.h"
@ -77,11 +79,13 @@ class nsDownloadScanner;
#endif
class nsDownloadManager : public nsIDownloadManager,
public nsINavHistoryObserver,
public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOWNLOADMANAGER
NS_DECL_NSINAVHISTORYOBSERVER
NS_DECL_NSIOBSERVER
nsresult Init();
@ -189,6 +193,14 @@ protected:
*/
nsresult RemoveAllDownloads();
/**
* Find all downloads from a source URI and delete them.
*
* @param aURI
* The source URI to remove downloads
*/
nsresult RemoveDownloadsForURI(nsIURI *aURI);
/**
* Callback used for resuming downloads after getting a wake notification.
*
@ -237,6 +249,8 @@ private:
nsCOMArray<nsDownload> mCurrentDownloads;
nsCOMPtr<nsIObserverService> mObserverService;
nsCOMPtr<mozIStorageStatement> mUpdateDownloadStatement;
nsCOMPtr<mozIStorageStatement> mGetIdsForURIStatement;
mozStorageTransaction *mHistoryTransaction;
static nsDownloadManager *gDownloadManagerService;

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

@ -0,0 +1,117 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Download Manager UI Test Code.
*
* The Initial Developer of the Original Code is
* Edward Lee <edward.lee@engineering.uiuc.edu>.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Test bug 251337 to make sure old downloads are expired and removed.
*/
function run_test()
{
let dm = Cc["@mozilla.org/download-manager;1"].
getService(Ci.nsIDownloadManager);
let db = dm.DBConnection;
// Empty any old downloads
db.executeSimpleSQL("DELETE FROM moz_downloads");
let stmt = db.createStatement(
"INSERT INTO moz_downloads (id, source, target, state) " +
"VALUES (?1, ?2, ?3, ?4)");
let iosvc = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
let theId = 1337;
let theURI = iosvc.newURI("http://expireme/please", null, null);
try {
// Add a download from the URI
stmt.bindInt32Parameter(0, theId);
stmt.bindStringParameter(1, theURI.spec);
// Give a dummy file name
let file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
file.append("expireTest");
stmt.bindStringParameter(2, Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).newFileURI(file).spec);
// Give it some state
stmt.bindInt32Parameter(3, dm.DOWNLOAD_FINISHED);
// Add it!
stmt.execute();
}
finally {
stmt.reset();
stmt.finalize();
}
let histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
// Add the download to places
histsvc.addVisit(theURI, Date.now() * 1000, null,
histsvc.TRANSITION_DOWNLOAD, false, 0);
// Look for the removed download notification
let obs = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
const kRemoveTopic = "download-manager-remove-download";
let testObs = {
observe: function(aSubject, aTopic, aData) {
if (aTopic != kRemoveTopic)
return;
// Make sure the removed/expired download was the one we added
let id = aSubject.QueryInterface(Ci.nsISupportsPRUint32);
do_check_eq(id.data, theId);
// We're done!
obs.removeObserver(testObs, kRemoveTopic);
do_test_finished();
}
};
obs.addObserver(testObs, kRemoveTopic, false);
// Set expiration stuff to 0 to make the download expire
let prefs = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
prefs.setIntPref("browser.history_expire_sites", 0);
prefs.setIntPref("browser.history_expire_days_min", 0);
prefs.setIntPref("browser.history_expire_days", 0);
// Expiration happens on a timeout after we set the pref
do_test_pending();
}

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

@ -43,11 +43,14 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
DIRS = public
ifdef MOZ_PLACES
DIRS += src
ifdef ENABLE_TESTS
DIRS += tests
endif
endif
include $(topsrcdir)/config/rules.mk

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

@ -47,14 +47,19 @@ MODULE = places
XPIDL_MODULE = places
XPIDLSRCS = \
nsINavHistoryService.idl \
$(NULL)
ifdef MOZ_PLACES
XPIDLSRCS += \
nsIAnnotationService.idl \
nsIBrowserHistory.idl \
nsIFaviconService.idl \
nsINavHistoryService.idl \
nsINavBookmarksService.idl \
nsILivemarkService.idl \
nsIDynamicContainer.idl \
nsITaggingService.idl \
$(NULL)
endif
include $(topsrcdir)/config/rules.mk

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

@ -2503,8 +2503,7 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRTime aTime, nsIURI* aReferringURI,
// the history UI (sidebar, history menu, url bar autocomplete, etc)
hidden = oldHiddenState;
if (hidden && (!aIsRedirect || aTransitionType == TRANSITION_TYPED) &&
aTransitionType != TRANSITION_EMBED &&
aTransitionType != TRANSITION_DOWNLOAD)
aTransitionType != TRANSITION_EMBED)
hidden = PR_FALSE; // unhide
typed = oldTypedState || (aTransitionType == TRANSITION_TYPED);
@ -2534,10 +2533,9 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRTime aTime, nsIURI* aReferringURI,
mDBGetPageVisitStats->Reset();
scoper.Abandon();
// Hide only embedded links, redirects, and downloads
// Hide only embedded links and redirects
// See the hidden computation code above for a little more explanation.
hidden = (aTransitionType == TRANSITION_EMBED || aIsRedirect ||
aTransitionType == TRANSITION_DOWNLOAD);
hidden = (aTransitionType == TRANSITION_EMBED || aIsRedirect);
typed = (aTransitionType == TRANSITION_TYPED);