Bug 1119462 - Allow unlimited quota for explicit persistent storage; r=bent
☠☠ backed out by ee220d48eab7 ☠ ☠
authorJan Varga <jan.varga@gmail.com>
Fri, 09 Jan 2015 01:24:54 +0100
changeset 248663 15830cc2b55b26588d57dff75597d84fd60ceed6
parent 248662 901e53fd2486a56905744801181ee7833b744de8
child 248664 dd1fc46d4d5694418fa1071ab6231237f0949c24
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs1119462
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1119462 - Allow unlimited quota for explicit persistent storage; r=bent
dom/indexedDB/ActorsParent.cpp
dom/indexedDB/test/mochitest.ini
dom/indexedDB/test/test_disabled_quota_prompt.html
dom/indexedDB/test/test_persistenceType.html
dom/quota/QuotaManager.cpp
dom/quota/QuotaManager.h
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -10847,16 +10847,24 @@ FactoryOp::CheckPermission(ContentParent
   bool isApp;
   bool hasUnlimStoragePerm;
   rv = QuotaManager::GetInfoFromPrincipal(principal, &group, &origin,
                                           &isApp, &hasUnlimStoragePerm);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
+#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
+  if (persistenceType == PERSISTENCE_TYPE_PERSISTENT &&
+      !QuotaManager::IsOriginWhitelistedForPersistentStorage(origin) &&
+      !isApp) {
+    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
+  }
+#endif
+
   PermissionRequestBase::PermissionValue permission;
 
   if (QuotaManager::IsFirstPromptRequired(persistenceType, origin, isApp)) {
 #ifdef MOZ_CHILD_PERMISSIONS
     if (aContentParent) {
       if (NS_WARN_IF(!AssertAppPrincipal(aContentParent, principal))) {
         IDB_REPORT_INTERNAL_ERR();
         return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
--- a/dom/indexedDB/test/mochitest.ini
+++ b/dom/indexedDB/test/mochitest.ini
@@ -147,18 +147,16 @@ skip-if = (buildapp == 'b2g' && toolkit 
 [test_cursor_update_updates_indexes.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_cursors.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_deleteDatabase.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_deleteDatabase_interactions.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
-[test_disabled_quota_prompt.html]
-skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_error_events_abort_transactions.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_event_propagation.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_event_source.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
 [test_exceptions_in_events.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
deleted file mode 100644
--- a/dom/indexedDB/test/test_disabled_quota_prompt.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!--
-  Any copyright is dedicated to the Public Domain.
-  http://creativecommons.org/publicdomain/zero/1.0/
--->
-<html>
-  <head>
-    <title>Indexed Database Property Test</title>
-
-    <script type="text/javascript"
-            src="/tests/SimpleTest/SimpleTest.js">
-    </script>
-
-    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-
-    <script type="text/javascript;version=1.7">
-      function addDataTo(objectStore)
-      {
-        const dataSize = 51200;
-
-        let buffer = new ArrayBuffer(dataSize);
-        for (let view = new Uint8Array(buffer), i = 0; i < dataSize; i++) {
-          view[i] = parseInt(Math.random() * 255)
-        }
-
-        let request = objectStore.put(buffer);
-        request.onerror = function(event) {
-          is(request.error.name,
-             "QuotaExceededError",
-             "correct error set on request");
-          SimpleTest.expectUncaughtException(true);
-          event.stopPropagation();
-        };
-        request.onsuccess = function() {
-          is(request.error, null, "no error yet, adding another value");
-          addDataTo(objectStore);
-        };
-      }
-
-      function testSteps()
-      {
-        const databaseName = window.location.pathname;
-        const databaseVersion = 1;
-        const databaseStorage = "persistent";
-        const objectStoreName = "foo";
-
-        info("setting quota pref");
-
-        SpecialPowers.pushPrefEnv({ set: [["dom.indexedDB.warningQuota", 2]] },
-                                  continueToNextStep);
-        yield undefined;
-
-        info("opening database");
-
-        let request = indexedDB.open(databaseName, {version: databaseVersion,
-                                                    storage: databaseStorage});
-        request.onerror = errorHandler;
-        request.onupgradeneeded = grabEventAndContinueHandler;
-        request.onsuccess = unexpectedSuccessHandler;
-        let event = yield undefined;
-
-        info("creating object store");
-
-        let db = event.target.result;
-        db.onerror = errorHandler;
-        db.onversionchange = function(event) {
-          is(event.oldVersion, databaseVersion, "got correct oldVersion");
-          is(event.newVersion, null, "got correct newVersion");
-          db.close();
-        };
-
-        let objectStore = db.createObjectStore(objectStoreName,
-                                               { autoIncrement: true });
-
-        request.onupgradeneeded = unexpectedSuccessHandler;
-        request.onsuccess = grabEventAndContinueHandler;
-        event = yield undefined;
-
-        info("making transaction");
-
-        let transaction = db.transaction(objectStoreName, "readwrite");
-        transaction.onabort = grabEventAndContinueHandler;
-        transaction.oncomplete = unexpectedSuccessHandler;
-
-        addDataTo(transaction.objectStore(objectStoreName));
-
-        info("adding until quota limit is reached");
-
-        event = yield undefined;
-
-        SimpleTest.expectUncaughtException(false);
-
-        is(transaction.error.name,
-           "QuotaExceededError",
-           "correct error set on transaction");
-
-        info("deleting database");
-
-        request = indexedDB.deleteDatabase(databaseName);
-        request.onerror = errorHandler;
-        request.onsuccess = grabEventAndContinueHandler;
-
-        event = yield undefined;
-
-        info("resetting quota pref");
-
-        SpecialPowers.popPrefEnv(continueToNextStep);
-        yield undefined;
-
-        finishTest();
-        yield undefined;
-      }
-    </script>
-
-    <script type="text/javascript;version=1.7" src="helpers.js"></script>
-
-  </head>
-
-  <body onload="runTest(true);"></body>
-
-</html>
--- a/dom/indexedDB/test/test_persistenceType.html
+++ b/dom/indexedDB/test/test_persistenceType.html
@@ -26,16 +26,31 @@
       catch (e) {
         ok(e instanceof TypeError, "Got TypeError.");
         is(e.name, "TypeError", "Good error name.");
       }
 
       for (let storage of storages) {
         let request = indexedDB.open(name, { version: version,
                                              storage: storage });
+
+        if (storage == "persistent" &&
+            (navigator.userAgent.indexOf("Android") != -1 ||
+             navigator.userAgent.indexOf("Mobile") != -1 ||
+             navigator.userAgent.indexOf("Tablet") != -1)) {
+          request.onerror = expectedErrorHandler("InvalidStateError");
+          request.onupgradeneeded = unexpectedSuccessHandler;
+          request.onsuccess = unexpectedSuccessHandler;
+          let event = yield undefined;
+
+          is(event.type, "error", "Got corrent event type");
+
+          continue;
+        }
+
         request.onerror = errorHandler;
         request.onupgradeneeded = grabEventAndContinueHandler;
         request.onsuccess = grabEventAndContinueHandler;
         let event = yield undefined;
 
         is(event.type, "upgradeneeded", "Got correct event type");
 
         let db = event.target.result;
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -791,30 +791,16 @@ SanitizeOriginString(nsCString& aOrigin)
   NS_ASSERTION(!strcmp(kReplaceChars,
                        FILE_ILLEGAL_CHARACTERS FILE_PATH_SEPARATOR),
                "Illegal file characters have changed!");
 #endif
 
   aOrigin.ReplaceChar(kReplaceChars, '+');
 }
 
-// The first prompt and quota tracking is not required for these origins in
-// persistent storage.
-bool
-IsPersistentOriginWhitelisted(const nsACString& aOrigin)
-{
-  if (aOrigin.EqualsLiteral(kChromeOrigin) ||
-      aOrigin.EqualsLiteral(kAboutHomeOrigin) ||
-      StringBeginsWith(aOrigin, nsDependentCString(kIndexedDBOriginPrefix))) {
-    return true;
-  }
-
-  return false;
-}
-
 nsresult
 CloneStoragePath(nsIFile* aBaseDir,
                  const nsACString& aStorageName,
                  nsAString& aStoragePath)
 {
   nsresult rv;
 
   nsCOMPtr<nsIFile> storageDir;
@@ -2718,16 +2704,31 @@ QuotaManager::GetInfoForChrome(nsACStrin
   }
   if (aHasUnlimStoragePerm) {
     *aHasUnlimStoragePerm = false;
   }
 }
 
 // static
 bool
+QuotaManager::IsOriginWhitelistedForPersistentStorage(const nsACString& aOrigin)
+{
+  // The first prompt and quota tracking is not required for these origins in
+  // persistent storage.
+  if (aOrigin.EqualsLiteral(kChromeOrigin) ||
+      aOrigin.EqualsLiteral(kAboutHomeOrigin) ||
+      StringBeginsWith(aOrigin, nsDependentCString(kIndexedDBOriginPrefix))) {
+    return true;
+  }
+
+  return false;
+}
+
+// static
+bool
 QuotaManager::IsTreatedAsPersistent(PersistenceType aPersistenceType,
                                     bool aIsApp)
 {
   if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT ||
       (aPersistenceType == PERSISTENCE_TYPE_DEFAULT && aIsApp)) {
     return true;
   }
 
@@ -2739,31 +2740,31 @@ bool
 QuotaManager::IsFirstPromptRequired(PersistenceType aPersistenceType,
                                     const nsACString& aOrigin,
                                     bool aIsApp)
 {
   if (IsTreatedAsTemporary(aPersistenceType, aIsApp)) {
     return false;
   }
 
-  return !IsPersistentOriginWhitelisted(aOrigin);
+  return !IsOriginWhitelistedForPersistentStorage(aOrigin);
 }
 
 // static
 bool
 QuotaManager::IsQuotaEnforced(PersistenceType aPersistenceType,
                               const nsACString& aOrigin,
                               bool aIsApp,
                               bool aHasUnlimStoragePerm)
 {
   if (IsTreatedAsTemporary(aPersistenceType, aIsApp)) {
     return true;
   }
 
-  if (IsPersistentOriginWhitelisted(aOrigin)) {
+  if (IsOriginWhitelistedForPersistentStorage(aOrigin)) {
     return false;
   }
 
   return !aHasUnlimStoragePerm;
 }
 
 // static
 void
@@ -3130,18 +3131,19 @@ QuotaManager::CancelPromptsForWindowInte
 
 bool
 QuotaManager::LockedQuotaIsLifted()
 {
   mQuotaMutex.AssertCurrentThreadOwns();
   MOZ_ASSERT(mCurrentWindowIndex != BAD_TLS_INDEX);
 
 #if 1
-  // XXX For now we always fail the quota prompt.
-  return false;
+  // XXX We disabled the second (quota) prompt. All related code is going away
+  //     soon.
+  return true;
 #else
   nsPIDOMWindow* window =
     static_cast<nsPIDOMWindow*>(PR_GetThreadPrivate(mCurrentWindowIndex));
 
   // Quota is not enforced in chrome contexts (e.g. for components and JSMs)
   // so we must have a window here.
   NS_ASSERTION(window, "Why don't we have a Window here?");
 
@@ -4771,17 +4773,18 @@ StorageDirectoryHelper::CreateOrUpgradeM
                                    originProps.mGroup,
                                    originProps.mOrigin,
                                    originProps.mIsApp);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
       // Move whitelisted origins to new persistent storage.
-      if (IsPersistentOriginWhitelisted(originProps.mSpec)) {
+      if (QuotaManager::IsOriginWhitelistedForPersistentStorage(
+                                                           originProps.mSpec)) {
         if (!permanentStorageDir) {
           permanentStorageDir =
             do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
           if (NS_WARN_IF(NS_FAILED(rv))) {
             return rv;
           }
 
           QuotaManager* quotaManager = QuotaManager::Get();
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -311,16 +311,19 @@ public:
 
   static void
   GetInfoForChrome(nsACString* aGroup,
                    nsACString* aOrigin,
                    bool* aIsApp,
                    bool* aHasUnlimStoragePerm);
 
   static bool
+  IsOriginWhitelistedForPersistentStorage(const nsACString& aOrigin);
+
+  static bool
   IsTreatedAsPersistent(PersistenceType aPersistenceType,
                         bool aIsApp);
 
   static bool
   IsTreatedAsTemporary(PersistenceType aPersistenceType,
                        bool aIsApp)
   {
     return !IsTreatedAsPersistent(aPersistenceType, aIsApp);