Bug 573061 - Add persistent cookie tests. Part 1: tweak listeners and add db close listener. r=sdwilsh
authorDan Witte <dwitte@mozilla.com>
Mon, 21 Jun 2010 17:50:35 -0700
changeset 43933 f4bd9605e451e616e95a876f4e637cfd3e7a6b12
parent 43932 a32ea115521e5131cf29c9362caeb7d6da69ed2b
child 43934 4f1f2e61ca9e023556a832dfb9b047c68f77021b
push idunknown
push userunknown
push dateunknown
reviewerssdwilsh
bugs573061
milestone1.9.3a6pre
Bug 573061 - Add persistent cookie tests. Part 1: tweak listeners and add db close listener. r=sdwilsh
netwerk/cookie/nsCookieService.cpp
netwerk/cookie/nsCookieService.h
--- 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,