Bug 573061 - Add persistent cookie tests. Part 1: tweak listeners and add db close listener. r=sdwilsh
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -67,16 +67,17 @@
#include "prtime.h"
#include "prprf.h"
#include "nsNetUtil.h"
#include "nsNetCID.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsIPrivateBrowsingService.h"
#include "nsNetCID.h"
#include "mozilla/storage.h"
+#include "mozIStorageCompletionCallback.h"
#include "mozilla/FunctionTimer.h"
/******************************************************************************
* nsCookieService impl:
* useful types & constants
******************************************************************************/
// XXX_hack. See bug 178993.
@@ -372,19 +373,18 @@ public:
aError->GetMessage(message);
COOKIE_LOGSTRING(PR_LOG_WARNING,
("Error %d occurred while performing a %s operation. Message: `%s`\n",
result, GetOpType(), message.get()));
#endif
return NS_OK;
}
};
-NS_IMETHODIMP_(nsrefcnt) DBListenerErrorHandler::AddRef() { return 2; }
-NS_IMETHODIMP_(nsrefcnt) DBListenerErrorHandler::Release() { return 1; }
-NS_IMPL_QUERY_INTERFACE1(DBListenerErrorHandler, mozIStorageStatementCallback)
+
+NS_IMPL_ISUPPORTS1(DBListenerErrorHandler, mozIStorageStatementCallback)
/******************************************************************************
* InsertCookieDBListener imp:
* Static mozIStorageStatementCallback used to track asynchronous insertion
* operations.
******************************************************************************/
class InsertCookieDBListener : public DBListenerErrorHandler
{
@@ -398,18 +398,16 @@ public:
return NS_OK;
}
NS_IMETHOD HandleCompletion(PRUint16 aReason)
{
return NS_OK;
}
};
-static InsertCookieDBListener sInsertCookieDBListener;
-
/******************************************************************************
* UpdateCookieDBListener imp:
* Static mozIStorageStatementCallback used to track asynchronous update
* operations.
******************************************************************************/
class UpdateCookieDBListener : public DBListenerErrorHandler
{
protected:
@@ -422,18 +420,16 @@ public:
return NS_OK;
}
NS_IMETHOD HandleCompletion(PRUint16 aReason)
{
return NS_OK;
}
};
-static UpdateCookieDBListener sUpdateCookieDBListener;
-
/******************************************************************************
* RemoveCookieDBListener imp:
* Static mozIStorageStatementCallback used to track asynchronous removal
* operations.
******************************************************************************/
class RemoveCookieDBListener : public DBListenerErrorHandler
{
protected:
@@ -446,17 +442,39 @@ public:
return NS_OK;
}
NS_IMETHOD HandleCompletion(PRUint16 aReason)
{
return NS_OK;
}
};
-static RemoveCookieDBListener sRemoveCookieDBListener;
+/******************************************************************************
+ * CloseCookieDBListener imp:
+ * Static mozIStorageCompletionCallback used to notify when the database is
+ * successfully closed.
+ ******************************************************************************/
+class CloseCookieDBListener : public mozIStorageCompletionCallback
+{
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Complete()
+ {
+ COOKIE_LOGSTRING(PR_LOG_DEBUG, ("Database closed"));
+
+ nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+ if (obs)
+ obs->NotifyObservers(nsnull, "cookie-db-closed", nsnull);
+
+ return NS_OK;
+ }
+};
+
+NS_IMPL_ISUPPORTS1(CloseCookieDBListener, mozIStorageCompletionCallback)
} // anonymous namespace
/******************************************************************************
* nsCookieService impl:
* singleton instance ctor/dtor methods
******************************************************************************/
@@ -561,16 +579,21 @@ nsCookieService::Init()
}
mPermissionService = do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
if (!mPermissionService) {
NS_WARNING("nsICookiePermission implementation not available - some features won't work!");
COOKIE_LOGSTRING(PR_LOG_WARNING, ("Init(): nsICookiePermission implementation not available"));
}
+ mInsertListener = new InsertCookieDBListener;
+ mUpdateListener = new InsertCookieDBListener;
+ mRemoveListener = new InsertCookieDBListener;
+ mCloseListener = new CloseCookieDBListener;
+
return NS_OK;
}
nsresult
nsCookieService::InitDB()
{
NS_ASSERTION(mDBState == &mDefaultDBState, "not in default DB state");
@@ -786,17 +809,17 @@ nsCookieService::CloseDB()
NS_ASSERTION(!mPrivateDBState.dbConn, "private DB connection should always be null");
// finalize our statements and close the db connection for the default state.
// since we own these objects, nulling the pointers is sufficient here.
mDefaultDBState.stmtInsert = nsnull;
mDefaultDBState.stmtDelete = nsnull;
mDefaultDBState.stmtUpdate = nsnull;
if (mDefaultDBState.dbConn) {
- mDefaultDBState.dbConn->AsyncClose(NULL);
+ mDefaultDBState.dbConn->AsyncClose(mCloseListener);
mDefaultDBState.dbConn = nsnull;
}
}
nsCookieService::~nsCookieService()
{
CloseDB();
@@ -1414,17 +1437,17 @@ nsCookieService::ImportCookies(nsIFile *
// If we need to write to disk, do so now.
if (paramsArray) {
PRUint32 length;
paramsArray->GetLength(&length);
if (length) {
rv = mDBState->stmtInsert->BindParameters(paramsArray);
NS_ASSERT_SUCCESS(rv);
nsCOMPtr<mozIStoragePendingStatement> handle;
- rv = mDBState->stmtInsert->ExecuteAsync(&sInsertCookieDBListener,
+ rv = mDBState->stmtInsert->ExecuteAsync(mInsertListener,
getter_AddRefs(handle));
NS_ASSERT_SUCCESS(rv);
}
}
COOKIE_LOGSTRING(PR_LOG_DEBUG, ("ImportCookies(): %ld cookies imported", mDBState->cookieCount));
@@ -1608,18 +1631,17 @@ nsCookieService::GetCookieInternal(nsIUR
// Update the database now if necessary.
if (paramsArray) {
PRUint32 length;
paramsArray->GetLength(&length);
if (length) {
nsresult rv = stmt->BindParameters(paramsArray);
NS_ASSERT_SUCCESS(rv);
nsCOMPtr<mozIStoragePendingStatement> handle;
- rv = stmt->ExecuteAsync(&sUpdateCookieDBListener,
- getter_AddRefs(handle));
+ rv = stmt->ExecuteAsync(mUpdateListener, getter_AddRefs(handle));
NS_ASSERT_SUCCESS(rv);
}
}
}
// return cookies in order of path length; longest to shortest.
// this is required per RFC2109. if cookies match in length,
// then sort by creation time (see bug 236772).
@@ -2615,17 +2637,17 @@ nsCookieService::PurgeCookies(PRInt64 aC
// Update the database if we have entries to purge.
if (paramsArray) {
PRUint32 length;
paramsArray->GetLength(&length);
if (length) {
nsresult rv = stmt->BindParameters(paramsArray);
NS_ASSERT_SUCCESS(rv);
nsCOMPtr<mozIStoragePendingStatement> handle;
- rv = stmt->ExecuteAsync(&sRemoveCookieDBListener, getter_AddRefs(handle));
+ rv = stmt->ExecuteAsync(mRemoveListener, getter_AddRefs(handle));
NS_ASSERT_SUCCESS(rv);
}
}
// take all the cookies in the removed list, and notify about them in one batch
NotifyChanged(removedList, NS_LITERAL_STRING("batch-deleted").get());
// reset the oldest time indicator
@@ -2803,18 +2825,17 @@ nsCookieService::RemoveCookieFromList(co
rv = paramsArray->AddParams(params);
NS_ASSERT_SUCCESS(rv);
// If we weren't given a params array, we'll need to remove it ourselves.
if (!aParamsArray) {
rv = stmt->BindParameters(paramsArray);
NS_ASSERT_SUCCESS(rv);
nsCOMPtr<mozIStoragePendingStatement> handle;
- rv = stmt->ExecuteAsync(&sRemoveCookieDBListener,
- getter_AddRefs(handle));
+ rv = stmt->ExecuteAsync(mRemoveListener, getter_AddRefs(handle));
NS_ASSERT_SUCCESS(rv);
}
}
if (aIter.entry->GetCookies().Length() == 1) {
// we're removing the last element in the array - so just remove the entry
// from the hash. note that the entryclass' dtor will take care of
// releasing this last element for us!
@@ -2909,18 +2930,17 @@ nsCookieService::AddCookieToList(const n
bindCookieParameters(paramsArray, aCookie);
// If we were supplied an array to store parameters, we shouldn't call
// executeAsync - someone up the stack will do this for us.
if (!aParamsArray) {
nsresult rv = stmt->BindParameters(paramsArray);
NS_ASSERT_SUCCESS(rv);
nsCOMPtr<mozIStoragePendingStatement> handle;
- rv = stmt->ExecuteAsync(&sInsertCookieDBListener,
- getter_AddRefs(handle));
+ rv = stmt->ExecuteAsync(mInsertListener, getter_AddRefs(handle));
NS_ASSERT_SUCCESS(rv);
}
}
return PR_TRUE;
}
void
--- a/netwerk/cookie/nsCookieService.h
+++ b/netwerk/cookie/nsCookieService.h
@@ -62,16 +62,19 @@ struct nsEnumerationData;
class nsICookiePermission;
class nsIEffectiveTLDService;
class nsIIDNService;
class nsIPrefBranch;
class nsIObserverService;
class nsIURI;
class nsIChannel;
+class DBListenerErrorHandler;
+class mozIStorageStatementCallback;
+class mozIStorageCompletionCallback;
// hash entry class
class nsCookieEntry : public PLDHashEntryHdr
{
public:
// Hash methods
typedef const nsCString& KeyType;
typedef const nsCString* KeyTypePointer;
@@ -217,16 +220,22 @@ class nsCookieService : public nsICookie
// private browsing, switching between them as appropriate. this state
// encapsulates both the in-memory table and the on-disk DB.
// note that the private states' dbConn should always be null - we never
// want to be dealing with the on-disk DB when in private browsing.
DBState *mDBState;
DBState mDefaultDBState;
DBState mPrivateDBState;
+ // DB completion handlers.
+ nsCOMPtr<mozIStorageStatementCallback> mInsertListener;
+ nsCOMPtr<mozIStorageStatementCallback> mUpdateListener;
+ nsCOMPtr<mozIStorageStatementCallback> mRemoveListener;
+ nsCOMPtr<mozIStorageCompletionCallback> mCloseListener;
+
// cached prefs
PRUint8 mCookieBehavior; // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT}
PRBool mThirdPartySession;
PRUint16 mMaxNumberOfCookies;
PRUint16 mMaxCookiesPerHost;
PRInt64 mCookiePurgeAge;
// private static member, used to cache a ptr to nsCookieService,