let chrome check globalStorage usage for a domain. b=396249, r=enndeakin, sr=jst, a=jst
authordcamp@mozilla.com
Wed, 03 Oct 2007 23:05:32 -0700
changeset 6643 3744aa02417d7e6a171605940af7e7c0f2d66668
parent 6642 086fdeddcd208de9e9d83367c01c60f13d42610a
child 6644 588e3cdde8fbbfbddfaf77388634a0f78aa985d8
push idunknown
push userunknown
push dateunknown
reviewersenndeakin, jst, jst
bugs396249
milestone1.9a9pre
let chrome check globalStorage usage for a domain. b=396249, r=enndeakin, sr=jst, a=jst
dom/public/idl/storage/Makefile.in
dom/public/idl/storage/nsIDOMStorageManager.idl
dom/src/storage/nsDOMStorage.cpp
dom/src/storage/nsDOMStorage.h
dom/src/storage/nsDOMStorageDB.cpp
dom/src/storage/nsDOMStorageDB.h
layout/build/nsLayoutCID.h
layout/build/nsLayoutModule.cpp
--- a/dom/public/idl/storage/Makefile.in
+++ b/dom/public/idl/storage/Makefile.in
@@ -47,16 +47,17 @@ XPIDL_MODULE   = dom_storage
 GRE_MODULE     = 1
 
 EXPORTS =                                      \
        nsPIDOMStorage.h                        \
        $(NULL)
 
 XPIDLSRCS =                                    \
        nsIDOMToString.idl                      \
+       nsIDOMStorageManager.idl                \
        $(NULL)
 
 SDK_XPIDLSRCS =                      \
         nsIDOMStorage.idl        \
         nsIDOMStorageEvent.idl   \
         nsIDOMStorageItem.idl    \
         nsIDOMStorageList.idl    \
         nsIDOMStorageWindow.idl  \
new file mode 100644
--- /dev/null
+++ b/dom/public/idl/storage/nsIDOMStorageManager.idl
@@ -0,0 +1,52 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(74dc93d1-8cdf-43b1-a52c-776dcb873475)]
+interface nsIDOMStorageManager : nsISupports
+{
+  /**
+   * Return the amount of disk space used by a domain.  Usage is checked
+   * against the domain of the page that set the key (the owner domain), not
+   * the domain of the storage object.
+   *
+   * @param aOwnerDomain The domain to check.
+   * @returns the space usage of the domain, in bytes.
+   */
+  long getUsage(in AString aOwnerDomain);
+};
--- a/dom/src/storage/nsDOMStorage.cpp
+++ b/dom/src/storage/nsDOMStorage.cpp
@@ -126,17 +126,19 @@ nsSessionStorageEntry::~nsSessionStorage
 }
 
 //
 // nsDOMStorageManager
 //
 
 nsDOMStorageManager* nsDOMStorageManager::gStorageManager;
 
-NS_IMPL_ISUPPORTS1(nsDOMStorageManager, nsIObserver)
+NS_IMPL_ISUPPORTS2(nsDOMStorageManager,
+                   nsIDOMStorageManager,
+                   nsIObserver)
 
 //static
 nsresult
 nsDOMStorageManager::Initialize()
 {
   gStorageManager = new nsDOMStorageManager();
   if (!gStorageManager)
     return NS_ERROR_OUT_OF_MEMORY;
@@ -152,16 +154,26 @@ nsDOMStorageManager::Initialize()
   nsCOMPtr<nsIObserverService> os = do_GetService("@mozilla.org/observer-service;1");
   if (os)
     os->AddObserver(gStorageManager, "cookie-changed", PR_FALSE);
 
   return NS_OK;
 }
 
 //static
+nsDOMStorageManager*
+nsDOMStorageManager::GetInstance()
+{
+  NS_ASSERTION(gStorageManager,
+               "nsDOMStorageManager::GetInstance() called before Initialize()");
+  NS_IF_ADDREF(gStorageManager);
+  return gStorageManager;
+}
+
+//static
 void
 nsDOMStorageManager::Shutdown()
 {
   NS_IF_RELEASE(gStorageManager);
   gStorageManager = nsnull;
 
 #ifdef MOZ_STORAGE
   delete nsDOMStorage::gStorageDB;
@@ -189,16 +201,26 @@ nsDOMStorageManager::Observe(nsISupports
     NS_ENSURE_SUCCESS(rv, rv);
     return nsDOMStorage::gStorageDB->RemoveAll();
 #endif
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDOMStorageManager::GetUsage(const nsAString& aDomain,
+                              PRInt32 *aUsage)
+{
+  nsresult rv = nsDOMStorage::InitDB();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return nsDOMStorage::gStorageDB->GetUsage(aDomain, aUsage);
+}
+
 void
 nsDOMStorageManager::AddToStoragesHash(nsDOMStorage* aStorage)
 {
   nsDOMStorageEntry* entry = mStorages.PutEntry(aStorage);
   if (entry)
     entry->mStorage = aStorage;
 }
 
--- a/dom/src/storage/nsDOMStorage.h
+++ b/dom/src/storage/nsDOMStorage.h
@@ -46,16 +46,17 @@
 #include "nsIDOMStorageList.h"
 #include "nsIDOMStorageItem.h"
 #include "nsInterfaceHashtable.h"
 #include "nsVoidArray.h"
 #include "nsPIDOMStorage.h"
 #include "nsIDOMToString.h"
 #include "nsDOMEvent.h"
 #include "nsIDOMStorageEvent.h"
+#include "nsIDOMStorageManager.h"
 
 #ifdef MOZ_STORAGE
 #include "nsDOMStorageDB.h"
 #endif
 
 class nsDOMStorage;
 class nsDOMStorageItem;
 
@@ -75,31 +76,36 @@ class nsSessionStorageEntry : public nsS
 public:
   nsSessionStorageEntry(KeyTypePointer aStr);
   nsSessionStorageEntry(const nsSessionStorageEntry& aToCopy);
   ~nsSessionStorageEntry();
 
   nsRefPtr<nsDOMStorageItem> mItem;
 };
 
-class nsDOMStorageManager : public nsIObserver
+class nsDOMStorageManager : public nsIDOMStorageManager
+                          , public nsIObserver
 {
 public:
   // nsISupports
   NS_DECL_ISUPPORTS
 
+  // nsIDOMStorageManager
+  NS_DECL_NSIDOMSTORAGEMANAGER
+
   // nsIObserver
   NS_DECL_NSIOBSERVER
 
   void AddToStoragesHash(nsDOMStorage* aStorage);
   void RemoveFromStoragesHash(nsDOMStorage* aStorage);
 
   nsresult ClearAllStorages();
 
   static nsresult Initialize();
+  static nsDOMStorageManager* GetInstance();
   static void Shutdown();
 
   static nsDOMStorageManager* gStorageManager;
 
 protected:
 
   nsTHashtable<nsDOMStorageEntry> mStorages;
 };
--- a/dom/src/storage/nsDOMStorageDB.cpp
+++ b/dom/src/storage/nsDOMStorageDB.cpp
@@ -266,22 +266,18 @@ nsDOMStorageDB::SetKey(const nsAString& 
                        const nsAString& aOwner,
                        PRInt32 aQuota)
 {
   mozStorageStatementScoper scope(mGetKeyValueStatement);
  
   PRInt32 usage = 0;
   nsresult rv;
   if (!aOwner.IsEmpty()) {
-    if (aOwner == mCachedOwner) {
-      usage = mCachedUsage;
-    } else {
-      rv = GetUsage(aOwner, &usage);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
+    rv = GetUsage(aOwner, &usage);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   usage += aKey.Length() + aValue.Length();
 
   rv = mGetKeyValueStatement->BindStringParameter(0, aDomain);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = mGetKeyValueStatement->BindStringParameter(1, aKey);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -421,24 +417,37 @@ nsDOMStorageDB::RemoveAll()
 {
   mozStorageStatementScoper scope(mRemoveAllStatement);
   return mRemoveAllStatement->Execute();
 }
 
 nsresult
 nsDOMStorageDB::GetUsage(const nsAString &aOwner, PRInt32 *aUsage)
 {
+  if (aOwner == mCachedOwner) {
+    *aUsage = mCachedUsage;
+    return NS_OK;
+  }
+
   mozStorageStatementScoper scope(mGetUsageStatement);
 
   nsresult rv = mGetUsageStatement->BindStringParameter(0, aOwner);
   NS_ENSURE_SUCCESS(rv, rv);
   
   PRBool exists;
   rv = mGetUsageStatement->ExecuteStep(&exists);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!exists) {
     *aUsage = 0;
     return NS_OK;
   }
   
-  return mGetUsageStatement->GetInt32(0, aUsage);
+  rv = mGetUsageStatement->GetInt32(0, aUsage);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!aOwner.IsEmpty()) {
+    mCachedOwner = aOwner;
+    mCachedUsage = *aUsage;
+  }
+
+  return NS_OK;
 }
--- a/dom/src/storage/nsDOMStorageDB.h
+++ b/dom/src/storage/nsDOMStorageDB.h
@@ -106,19 +106,19 @@ public:
             PRInt32 aKeyUsage);
 
   /**
    * Removes all keys from storage. Used when clearing storage.
    */
   nsresult
   RemoveAll();
 
-protected:
+  nsresult GetUsage(const nsAString &aOwner, PRInt32 *aUsage);
 
-  nsresult GetUsage(const nsAString &aOwner, PRInt32 *aUsage);
+protected:
 
   nsCOMPtr<mozIStorageConnection> mConnection;
 
   nsCOMPtr<mozIStorageStatement> mGetAllKeysStatement;
   nsCOMPtr<mozIStorageStatement> mGetKeyValueStatement;
   nsCOMPtr<mozIStorageStatement> mInsertKeyStatement;
   nsCOMPtr<mozIStorageStatement> mUpdateKeyStatement;
   nsCOMPtr<mozIStorageStatement> mSetSecureStatement;
--- a/layout/build/nsLayoutCID.h
+++ b/layout/build/nsLayoutCID.h
@@ -209,9 +209,13 @@
 // {a35d1cd4-c505-4d2d-a0f9-aef00b7ce5a5}
 #define NS_CANVASRENDERINGCONTEXT2D_CID \
 { 0xa35d1cd4, 0xc505, 0x4d2d, { 0xa0, 0xf9, 0xae, 0xf0, 0x0b, 0x7c, 0xe5, 0xa5 } }
 
 // {8b449142-1eab-4bfa-9830-fab6ebb09774}
 #define NS_DOMSTORAGE_CID \
 { 0x8b449142, 0x1eab, 0x4bfa, { 0x98, 0x30, 0xfa, 0xb6, 0xeb, 0xb0, 0x97, 0x74 } }
 
+// {b88a4712-eb52-4c10-9b85-bf5894b510f0}
+#define NS_DOMSTORAGEMANAGER_CID               \
+{ 0xb88a4712, 0xeb52, 0x4c10, { 0x9b, 0x85, 0xbf, 0x58, 0x94, 0xb5, 0x10, 0xf0 } }
+
 #endif /* nsLayoutCID_h__ */
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -278,16 +278,18 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsXPath1S
 
 // Factory Constructor
 NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
 NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsXPathEvaluator, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsXMLHttpRequest)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager,
+                                         nsDOMStorageManager::GetInstance)
 
 //-----------------------------------------------------------------------------
 
 // Per bug 209804, it is necessary to observe the "xpcom-shutdown" event and
 // perform shutdown of the layout modules at that time instead of waiting for
 // our module destructor to run.  If we do not do this, then we risk holding
 // references to objects in other component libraries that have already been
 // shutdown (and possibly unloaded if 60709 is ever fixed).
@@ -1302,16 +1304,21 @@ static const nsModuleComponentInfo gComp
     NS_DOMPARSER_CONTRACTID,
     nsDOMParserConstructor },
 
   { "DOM Storage",
     NS_DOMSTORAGE_CID,
     "@mozilla.org/dom/storage;1",
     NS_NewDOMStorage },
 
+  { "DOM Storage Manager",
+    NS_DOMSTORAGEMANAGER_CID,
+    "@mozilla.org/dom/storagemanager;1",
+    nsDOMStorageManagerConstructor },
+
   { "Text Editor",
     NS_TEXTEDITOR_CID,
     "@mozilla.org/editor/texteditor;1",
     nsPlaintextEditorConstructor },
 
 #ifndef MOZILLA_PLAINTEXT_EDITOR_ONLY
 #ifdef ENABLE_EDITOR_API_LOG
     { "HTML Editor",