Merge remote-tracking branch 'origin/master' into custom

This commit is contained in:
Roy Tam 2019-11-08 20:30:31 +08:00
commit 27884ac351
378 changed files with 763 additions and 33253 deletions

View file

@ -4427,18 +4427,6 @@ CreateStorageConnection(nsIFile* aDBFile,
nsresult rv;
bool exists;
if (IndexedDatabaseManager::InLowDiskSpaceMode()) {
rv = aDBFile->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!exists) {
NS_WARNING("Refusing to create database because disk space is low!");
return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
}
}
nsCOMPtr<nsIFileURL> dbFileUrl;
rv = GetDatabaseFileURL(aDBFile,
aPersistenceType,
@ -19103,23 +19091,6 @@ DatabaseMaintenance::DetermineMaintenanceAction(
return NS_OK;
}
bool lowDiskSpace = IndexedDatabaseManager::InLowDiskSpaceMode();
if (QuotaManager::IsRunningXPCShellTests()) {
// If we're running XPCShell then we want to test both the low disk space
// and normal disk space code paths so pick semi-randomly based on the
// current time.
lowDiskSpace = ((PR_Now() / PR_USEC_PER_MSEC) % 2) == 0;
}
// If we're low on disk space then the best we can hope for is that an
// incremental vacuum might free some space. That is a journaled operation so
// it may not be possible even then.
if (lowDiskSpace) {
*aMaintenanceAction = MaintenanceAction::IncrementalVacuum;
return NS_OK;
}
// This method shouldn't make any permanent changes to the database, so make
// sure everything gets rolled back when we leave.
mozStorageTransaction transaction(aConnection,
@ -24233,11 +24204,6 @@ CreateFileOp::DoDatabaseWork()
"CreateFileOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
NS_WARNING("Refusing to create file because disk space is low!");
return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
}
if (NS_WARN_IF(QuotaManager::IsShuttingDown()) || !OperationMayProceed()) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
@ -24378,10 +24344,6 @@ CreateObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
"CreateObjectStoreOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
}
#ifdef DEBUG
{
// Make sure that we're not creating an object store with the same name as
@ -24705,10 +24667,6 @@ RenameObjectStoreOp::DoDatabaseWork(DatabaseConnection* aConnection)
"RenameObjectStoreOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
}
#ifdef DEBUG
{
// Make sure that we're not renaming an object store with the same name as
@ -24798,7 +24756,6 @@ CreateIndexOp::InsertDataFromObjectStore(DatabaseConnection* aConnection)
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(!IndexedDatabaseManager::InLowDiskSpaceMode());
MOZ_ASSERT(mMaybeUniqueIndexTable);
PROFILER_LABEL("IndexedDB",
@ -24849,7 +24806,6 @@ CreateIndexOp::InsertDataFromObjectStoreInternal(
{
MOZ_ASSERT(aConnection);
aConnection->AssertIsOnConnectionThread();
MOZ_ASSERT(!IndexedDatabaseManager::InLowDiskSpaceMode());
MOZ_ASSERT(mMaybeUniqueIndexTable);
DebugOnly<void*> storageConnection = aConnection->GetStorageConnection();
@ -24926,10 +24882,6 @@ CreateIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
"CreateIndexOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
}
#ifdef DEBUG
{
// Make sure that we're not creating an index with the same name and object
@ -25806,10 +25758,6 @@ RenameIndexOp::DoDatabaseWork(DatabaseConnection* aConnection)
"RenameIndexOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
}
#ifdef DEBUG
{
// Make sure that we're not renaming an index with the same name as another
@ -26294,10 +26242,6 @@ ObjectStoreAddOrPutRequestOp::DoDatabaseWork(DatabaseConnection* aConnection)
"ObjectStoreAddOrPutRequestOp::DoDatabaseWork",
js::ProfileEntry::Category::STORAGE);
if (NS_WARN_IF(IndexedDatabaseManager::InLowDiskSpaceMode())) {
return NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR;
}
DatabaseConnection::AutoSavepoint autoSave;
nsresult rv = autoSave.Start(Transaction());
if (NS_WARN_IF(NS_FAILED(rv))) {

View file

@ -8,11 +8,9 @@
#include "chrome/common/ipc_channel.h" // for IPC::Channel::kMaximumMessageSize
#include "nsIConsoleService.h"
#include "nsIDiskSpaceWatcher.h"
#include "nsIDOMWindow.h"
#include "nsIEventTarget.h"
#include "nsIFile.h"
#include "nsIObserverService.h"
#include "nsIScriptError.h"
#include "nsIScriptGlobalObject.h"
@ -64,11 +62,6 @@
#define IDB_STR "indexedDB"
// The two possible values for the data argument when receiving the disk space
// observer notification.
#define LOW_DISK_SPACE_DATA_FULL "full"
#define LOW_DISK_SPACE_DATA_FREE "free"
namespace mozilla {
namespace dom {
namespace indexedDB {
@ -313,8 +306,6 @@ Atomic<IndexedDatabaseManager::LoggingMode>
IndexedDatabaseManager::sLoggingMode(
IndexedDatabaseManager::Logging_Disabled);
mozilla::Atomic<bool> IndexedDatabaseManager::sLowDiskSpaceMode(false);
// static
IndexedDatabaseManager*
IndexedDatabaseManager::GetOrCreate()
@ -329,24 +320,6 @@ IndexedDatabaseManager::GetOrCreate()
if (!gDBManager) {
sIsMainProcess = XRE_IsParentProcess();
if (sIsMainProcess && Preferences::GetBool("disk_space_watcher.enabled", false)) {
// See if we're starting up in low disk space conditions.
nsCOMPtr<nsIDiskSpaceWatcher> watcher =
do_GetService(DISKSPACEWATCHER_CONTRACTID);
if (watcher) {
bool isDiskFull;
if (NS_SUCCEEDED(watcher->GetIsDiskFull(&isDiskFull))) {
sLowDiskSpaceMode = isDiskFull;
}
else {
NS_WARNING("GetIsDiskFull failed!");
}
}
else {
NS_WARNING("No disk space watcher component available!");
}
}
RefPtr<IndexedDatabaseManager> instance(new IndexedDatabaseManager());
nsresult rv = instance->Init();
@ -380,13 +353,6 @@ IndexedDatabaseManager::Init()
// During Init() we can't yet call IsMainProcess(), just check sIsMainProcess
// directly.
if (sIsMainProcess) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
NS_ENSURE_STATE(obs);
nsresult rv =
obs->AddObserver(this, DISKSPACEWATCHER_OBSERVER_TOPIC, false);
NS_ENSURE_SUCCESS(rv, rv);
mDeleteTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
NS_ENSURE_STATE(mDeleteTimer);
@ -680,16 +646,6 @@ IndexedDatabaseManager::IsMainProcess()
return sIsMainProcess;
}
//static
bool
IndexedDatabaseManager::InLowDiskSpaceMode()
{
NS_ASSERTION(gDBManager,
"InLowDiskSpaceMode() called before indexedDB has been "
"initialized!");
return sLowDiskSpaceMode;
}
// static
IndexedDatabaseManager::LoggingMode
IndexedDatabaseManager::GetLoggingMode()
@ -1087,36 +1043,7 @@ IndexedDatabaseManager::GetLocale()
NS_IMPL_ADDREF(IndexedDatabaseManager)
NS_IMPL_RELEASE_WITH_DESTROY(IndexedDatabaseManager, Destroy())
NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIObserver, nsITimerCallback)
NS_IMETHODIMP
IndexedDatabaseManager::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
NS_ASSERTION(IsMainProcess(), "Wrong process!");
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!strcmp(aTopic, DISKSPACEWATCHER_OBSERVER_TOPIC)) {
NS_ASSERTION(aData, "No data?!");
const nsDependentString data(aData);
if (data.EqualsLiteral(LOW_DISK_SPACE_DATA_FULL)) {
sLowDiskSpaceMode = true;
}
else if (data.EqualsLiteral(LOW_DISK_SPACE_DATA_FREE)) {
sLowDiskSpaceMode = false;
}
else {
NS_NOTREACHED("Unknown data value!");
}
return NS_OK;
}
NS_NOTREACHED("Unknown topic!");
return NS_ERROR_UNEXPECTED;
}
NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsITimerCallback)
NS_IMETHODIMP
IndexedDatabaseManager::Notify(nsITimer* aTimer)

View file

@ -7,8 +7,6 @@
#ifndef mozilla_dom_indexeddatabasemanager_h__
#define mozilla_dom_indexeddatabasemanager_h__
#include "nsIObserver.h"
#include "js/TypeDecls.h"
#include "mozilla/Atomics.h"
#include "mozilla/dom/quota/PersistenceType.h"
@ -43,8 +41,7 @@ class FileManagerInfo;
} // namespace indexedDB
class IndexedDatabaseManager final
: public nsIObserver
, public nsITimerCallback
: public nsITimerCallback
{
typedef mozilla::dom::quota::PersistenceType PersistenceType;
typedef mozilla::dom::quota::QuotaManager QuotaManager;
@ -62,7 +59,6 @@ public:
};
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_DECL_NSITIMERCALLBACK
// Returns a non-owning reference.
@ -86,16 +82,6 @@ public:
}
#endif
static bool
InLowDiskSpaceMode()
#ifdef DEBUG
;
#else
{
return !!sLowDiskSpaceMode;
}
#endif
static bool
InTestingMode();
@ -244,7 +230,6 @@ private:
static bool sFullSynchronousMode;
static LazyLogModule sLoggingModule;
static Atomic<LoggingMode> sLoggingMode;
static mozilla::Atomic<bool> sLowDiskSpaceMode;
};
} // namespace dom

View file

@ -217,10 +217,6 @@ if (!window.runTest) {
function finishTest()
{
SpecialPowers.notifyObserversInParentProcess(null,
"disk-space-watcher",
"free");
SimpleTest.executeSoon(function() {
testGenerator.close();
testHarnessGenerator.close();

View file

@ -66,7 +66,6 @@ support-files =
unit/test_locale_aware_indexes.js
unit/test_locale_aware_index_getAll.js
unit/test_locale_aware_index_getAllObjects.js
unit/test_lowDiskSpace.js
unit/test_maximal_serialized_object_size.js
unit/test_multientry.js
unit/test_names_sorted.js
@ -214,7 +213,6 @@ skip-if = true
[test_key_requirements.html]
[test_keys.html]
[test_leaving_page.html]
[test_lowDiskSpace.html]
[test_maximal_serialized_object_size.html]
[test_message_manager_ipc.html]
# This test is only supposed to run in the main process.

View file

@ -1,19 +0,0 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Low Disk Space 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" src="unit/test_lowDiskSpace.js"></script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>

View file

@ -1,754 +0,0 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
"use strict";
var disableWorkerTest = "This test uses SpecialPowers";
var self = this;
var testGenerator = testSteps();
function testSteps()
{
const dbName = self.window ? window.location.pathname : "test_lowDiskSpace";
const dbVersion = 1;
const objectStoreName = "foo";
const objectStoreOptions = { keyPath: "foo" };
const indexName = "bar";
const indexOptions = { unique: true };
const dbData = [
{ foo: 0, bar: 0 },
{ foo: 1, bar: 10 },
{ foo: 2, bar: 20 },
{ foo: 3, bar: 30 },
{ foo: 4, bar: 40 },
{ foo: 5, bar: 50 },
{ foo: 6, bar: 60 },
{ foo: 7, bar: 70 },
{ foo: 8, bar: 80 },
{ foo: 9, bar: 90 }
];
let lowDiskMode = false;
function setLowDiskMode(val) {
let data = val ? "full" : "free";
if (val == lowDiskMode) {
info("Low disk mode is: " + data);
}
else {
info("Changing low disk mode to: " + data);
SpecialPowers.notifyObserversInParentProcess(null, "disk-space-watcher",
data);
lowDiskMode = val;
}
}
{ // Make sure opening works from the beginning.
info("Test 1");
setLowDiskMode(false);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(event.type, "success", "Opened database without setting low disk mode");
let db = event.target.result;
db.close();
}
{ // Make sure delete works in low disk mode.
info("Test 2");
setLowDiskMode(true);
let request = indexedDB.deleteDatabase(dbName);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(event.type, "success", "Deleted database after setting low disk mode");
}
{ // Make sure creating a db in low disk mode fails.
info("Test 3");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = expectedErrorHandler("QuotaExceededError");
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "error", "Didn't create new database in low disk mode");
}
{ // Make sure opening an already-existing db in low disk mode succeeds.
info("Test 4");
setLowDiskMode(false);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
let db = event.target.result;
db.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Created database");
ok(event.target.result === db, "Got the same database");
db.close();
setLowDiskMode(true);
request = indexedDB.open(dbName);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Opened existing database in low disk mode");
db = event.target.result;
db.close();
}
{ // Make sure upgrading an already-existing db in low disk mode succeeds.
info("Test 5");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion + 1);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
let db = event.target.result;
db.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Created database");
ok(event.target.result === db, "Got the same database");
db.close();
}
{ // Make sure creating objectStores in low disk mode fails.
info("Test 6");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion + 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
let db = event.target.result;
db.onerror = errorHandler;
let txn = event.target.transaction;
txn.onerror = expectedErrorHandler("AbortError");
txn.onabort = grabEventAndContinueHandler;
let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
request.onupgradeneeded = unexpectedSuccessHandler;
event = yield undefined;
is(event.type, "abort", "Got correct event type");
is(event.target.error.name, "QuotaExceededError", "Got correct error type");
request.onerror = expectedErrorHandler("AbortError");
event = yield undefined;
}
{ // Make sure creating indexes in low disk mode fails.
info("Test 7");
setLowDiskMode(false);
let request = indexedDB.open(dbName, dbVersion + 2);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
let db = event.target.result;
db.onerror = errorHandler;
let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Upgraded database");
ok(event.target.result === db, "Got the same database");
db.close();
setLowDiskMode(true);
request = indexedDB.open(dbName, dbVersion + 3);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
db = event.target.result;
db.onerror = errorHandler;
let txn = event.target.transaction;
txn.onerror = expectedErrorHandler("AbortError");
txn.onabort = grabEventAndContinueHandler;
objectStore = event.target.transaction.objectStore(objectStoreName);
let index = objectStore.createIndex(indexName, indexName, indexOptions);
request.onupgradeneeded = unexpectedSuccessHandler;
event = yield undefined;
is(event.type, "abort", "Got correct event type");
is(event.target.error.name, "QuotaExceededError", "Got correct error type");
request.onerror = expectedErrorHandler("AbortError");
event = yield undefined;
}
{ // Make sure deleting indexes in low disk mode succeeds.
info("Test 8");
setLowDiskMode(false);
let request = indexedDB.open(dbName, dbVersion + 3);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
let db = event.target.result;
db.onerror = errorHandler;
let objectStore = event.target.transaction.objectStore(objectStoreName);
let index = objectStore.createIndex(indexName, indexName, indexOptions);
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Upgraded database");
ok(event.target.result === db, "Got the same database");
db.close();
setLowDiskMode(true);
request = indexedDB.open(dbName, dbVersion + 4);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
db = event.target.result;
db.onerror = errorHandler;
objectStore = event.target.transaction.objectStore(objectStoreName);
objectStore.deleteIndex(indexName);
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Upgraded database");
ok(event.target.result === db, "Got the same database");
db.close();
}
{ // Make sure deleting objectStores in low disk mode succeeds.
info("Test 9");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion + 5);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
let db = event.target.result;
db.onerror = errorHandler;
db.deleteObjectStore(objectStoreName);
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Upgraded database");
ok(event.target.result === db, "Got the same database");
db.close();
// Reset everything.
indexedDB.deleteDatabase(dbName);
}
{ // Add data that the rest of the tests will use.
info("Adding test data");
setLowDiskMode(false);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = unexpectedSuccessHandler;
let event = yield undefined;
is(event.type, "upgradeneeded", "Upgrading database");
let db = event.target.result;
db.onerror = errorHandler;
let objectStore = db.createObjectStore(objectStoreName, objectStoreOptions);
let index = objectStore.createIndex(indexName, indexName, indexOptions);
for (let data of dbData) {
objectStore.add(data);
}
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Upgraded database");
ok(event.target.result === db, "Got the same database");
db.close();
}
{ // Make sure read operations in readonly transactions succeed in low disk
// mode.
info("Test 10");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
let transaction = db.transaction(objectStoreName);
let objectStore = transaction.objectStore(objectStoreName);
let index = objectStore.index(indexName);
let data = dbData[0];
let requestCounter = new RequestCounter();
objectStore.get(data.foo).onsuccess = requestCounter.handler();
objectStore.mozGetAll().onsuccess = requestCounter.handler();
objectStore.count().onsuccess = requestCounter.handler();
index.get(data.bar).onsuccess = requestCounter.handler();
index.mozGetAll().onsuccess = requestCounter.handler();
index.getKey(data.bar).onsuccess = requestCounter.handler();
index.mozGetAllKeys().onsuccess = requestCounter.handler();
index.count().onsuccess = requestCounter.handler();
let objectStoreDataCount = 0;
request = objectStore.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
objectStoreDataCount++;
objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(objectStoreDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
let indexDataCount = 0;
request = index.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
indexDataCount++;
indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(indexDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
let indexKeyDataCount = 0;
request = index.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
indexKeyDataCount++;
indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(indexKeyDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
// Wait for all requests.
yield undefined;
transaction.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "complete", "Transaction succeeded");
db.close();
}
{ // Make sure read operations in readwrite transactions succeed in low disk
// mode.
info("Test 11");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
let transaction = db.transaction(objectStoreName, "readwrite");
let objectStore = transaction.objectStore(objectStoreName);
let index = objectStore.index(indexName);
let data = dbData[0];
let requestCounter = new RequestCounter();
objectStore.get(data.foo).onsuccess = requestCounter.handler();
objectStore.mozGetAll().onsuccess = requestCounter.handler();
objectStore.count().onsuccess = requestCounter.handler();
index.get(data.bar).onsuccess = requestCounter.handler();
index.mozGetAll().onsuccess = requestCounter.handler();
index.getKey(data.bar).onsuccess = requestCounter.handler();
index.mozGetAllKeys().onsuccess = requestCounter.handler();
index.count().onsuccess = requestCounter.handler();
let objectStoreDataCount = 0;
request = objectStore.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
objectStoreDataCount++;
objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(objectStoreDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
let indexDataCount = 0;
request = index.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
indexDataCount++;
indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(indexDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
let indexKeyDataCount = 0;
request = index.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
indexKeyDataCount++;
indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(indexKeyDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
// Wait for all requests.
yield undefined;
transaction.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "complete", "Transaction succeeded");
db.close();
}
{ // Make sure write operations in readwrite transactions fail in low disk
// mode.
info("Test 12");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
let transaction = db.transaction(objectStoreName, "readwrite");
let objectStore = transaction.objectStore(objectStoreName);
let index = objectStore.index(indexName);
let data = dbData[0];
let newData = { foo: 999, bar: 999 };
let requestCounter = new RequestCounter();
objectStore.add(newData).onerror = requestCounter.errorHandler();
objectStore.put(newData).onerror = requestCounter.errorHandler();
objectStore.get(data.foo).onsuccess = requestCounter.handler();
objectStore.mozGetAll().onsuccess = requestCounter.handler();
objectStore.count().onsuccess = requestCounter.handler();
index.get(data.bar).onsuccess = requestCounter.handler();
index.mozGetAll().onsuccess = requestCounter.handler();
index.getKey(data.bar).onsuccess = requestCounter.handler();
index.mozGetAllKeys().onsuccess = requestCounter.handler();
index.count().onsuccess = requestCounter.handler();
let objectStoreDataCount = 0;
request = objectStore.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
objectStoreDataCount++;
cursor.update(cursor.value).onerror = requestCounter.errorHandler();
objectStoreDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(objectStoreDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
let indexDataCount = 0;
request = index.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
indexDataCount++;
cursor.update(cursor.value).onerror = requestCounter.errorHandler();
indexDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(indexDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
let indexKeyDataCount = 0;
request = index.openCursor();
request.onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
indexKeyDataCount++;
cursor.update(cursor.value).onerror = requestCounter.errorHandler();
indexKeyDataCount % 2 ? cursor.continue() : cursor.advance(1);
}
else {
is(indexKeyDataCount, dbData.length, "Saw all data");
requestCounter.decr();
}
};
requestCounter.incr();
// Wait for all requests.
yield undefined;
transaction.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "complete", "Transaction succeeded");
db.close();
}
{ // Make sure deleting operations in readwrite transactions succeed in low
// disk mode.
info("Test 13");
setLowDiskMode(true);
let request = indexedDB.open(dbName, dbVersion);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
let db = event.target.result;
db.onerror = errorHandler;
let transaction = db.transaction(objectStoreName, "readwrite");
let objectStore = transaction.objectStore(objectStoreName);
let index = objectStore.index(indexName);
let dataIndex = 0;
let data = dbData[dataIndex++];
let requestCounter = new RequestCounter();
objectStore.delete(data.foo).onsuccess = requestCounter.handler();
objectStore.openCursor().onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
cursor.delete().onsuccess = requestCounter.handler();
}
requestCounter.decr();
};
requestCounter.incr();
index.openCursor(null, "prev").onsuccess = function(event) {
let cursor = event.target.result;
if (cursor) {
cursor.delete().onsuccess = requestCounter.handler();
}
requestCounter.decr();
};
requestCounter.incr();
yield undefined;
objectStore.count().onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result, dbData.length - 3, "Actually deleted something");
objectStore.clear();
objectStore.count().onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.target.result, 0, "Actually cleared");
transaction.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "complete", "Transaction succeeded");
db.close();
}
finishTest();
yield undefined;
}
function RequestCounter(expectedType) {
this._counter = 0;
}
RequestCounter.prototype = {
incr: function() {
this._counter++;
},
decr: function() {
if (!--this._counter) {
continueToNextStepSync();
}
},
handler: function(type, preventDefault) {
this.incr();
return function(event) {
is(event.type, type || "success", "Correct type");
this.decr();
}.bind(this);
},
errorHandler: function(eventType, errorName) {
this.incr();
return function(event) {
is(event.type, eventType || "error", "Correct type");
is(event.target.error.name, errorName || "QuotaExceededError",
"Correct error name");
event.preventDefault();
event.stopPropagation();
this.decr();
}.bind(this);
}
};

View file

@ -66,9 +66,6 @@ function finishTest()
resetWasm();
resetExperimental();
resetTesting();
SpecialPowers.notifyObserversInParentProcess(null, "disk-space-watcher",
"free");
}
SpecialPowers.removeFiles();

View file

@ -46,7 +46,6 @@ skip-if = toolkit == 'android'
[test_invalidate.js]
# disabled for the moment.
skip-if = true
[test_lowDiskSpace.js]
[test_maximal_serialized_object_size.js]
[test_metadata2Restore.js]
[test_metadataRestore.js]

View file

@ -205,11 +205,6 @@ DOMStorageCache::ProcessUsageDelta(const DOMStorage* aStorage, int64_t aDelta)
bool
DOMStorageCache::ProcessUsageDelta(uint32_t aGetDataSetIndex, const int64_t aDelta)
{
// Check if we are in a low disk space situation
if (aDelta > 0 && mManager && mManager->IsLowDiskSpace()) {
return false;
}
// Check limit per this origin
Data& data = mData[aGetDataSetIndex];
uint64_t newOriginUsage = data.mOriginQuotaUsage + aDelta;

View file

@ -11,7 +11,6 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/Unused.h"
#include "nsIDiskSpaceWatcher.h"
#include "nsThreadUtils.h"
namespace mozilla {
@ -321,22 +320,6 @@ private:
mozilla::Unused << mParent->SendOriginsHavingData(scopes);
}
// We need to check if the device is in a low disk space situation, so
// we can forbid in that case any write in localStorage.
nsCOMPtr<nsIDiskSpaceWatcher> diskSpaceWatcher =
do_GetService("@mozilla.org/toolkit/disk-space-watcher;1");
if (!diskSpaceWatcher) {
return NS_OK;
}
bool lowDiskSpace = false;
diskSpaceWatcher->GetIsDiskFull(&lowDiskSpace);
if (lowDiskSpace) {
mozilla::Unused << mParent->SendObserve(
nsDependentCString("low-disk-space"), EmptyString(), EmptyCString());
}
return NS_OK;
}

View file

@ -103,7 +103,6 @@ NS_IMPL_ISUPPORTS(DOMStorageManager,
DOMStorageManager::DOMStorageManager(DOMStorage::StorageType aType)
: mCaches(8)
, mType(aType)
, mLowDiskSpace(false)
{
DOMStorageObserver* observer = DOMStorageObserver::Self();
NS_ASSERTION(observer, "No DOMStorageObserver, cannot observe private data delete notifications!");
@ -566,22 +565,6 @@ DOMStorageManager::Observe(const char* aTopic,
return NS_OK;
}
if (!strcmp(aTopic, "low-disk-space")) {
if (mType == LocalStorage) {
mLowDiskSpace = true;
}
return NS_OK;
}
if (!strcmp(aTopic, "no-low-disk-space")) {
if (mType == LocalStorage) {
mLowDiskSpace = false;
}
return NS_OK;
}
#ifdef DOM_STORAGE_TESTS
if (!strcmp(aTopic, "test-reload")) {
if (mType != LocalStorage) {

View file

@ -102,12 +102,6 @@ private:
const DOMStorage::StorageType mType;
// If mLowDiskSpace is true it indicates a low device storage situation and
// so no localStorage writes are allowed. sessionStorage writes are still
// allowed.
bool mLowDiskSpace;
bool IsLowDiskSpace() const { return mLowDiskSpace; };
void ClearCaches(uint32_t aUnloadFlags,
const OriginAttributesPattern& aPattern,
const nsACString& aKeyPrefix);

View file

@ -70,9 +70,6 @@ DOMStorageObserver::Init()
obs->AddObserver(sSelf, "profile-before-change", true);
obs->AddObserver(sSelf, "xpcom-shutdown", true);
// Observe low device storage notifications.
obs->AddObserver(sSelf, "disk-space-watcher", true);
#ifdef DOM_STORAGE_TESTS
// Testing
obs->AddObserver(sSelf, "domstorage-test-flush-force", true);
@ -313,16 +310,6 @@ DOMStorageObserver::Observe(nsISupports* aSubject,
return NS_OK;
}
if (!strcmp(aTopic, "disk-space-watcher")) {
if (NS_LITERAL_STRING("full").Equals(aData)) {
Notify("low-disk-space");
} else if (NS_LITERAL_STRING("free").Equals(aData)) {
Notify("no-low-disk-space");
}
return NS_OK;
}
#ifdef DOM_STORAGE_TESTS
if (!strcmp(aTopic, "domstorage-test-flush-force")) {
DOMStorageDBBridge* db = DOMStorageCache::GetDatabase();

View file

@ -79,8 +79,6 @@ support-files =
[test_fallback.html]
[test_foreign.html]
[test_identicalManifest.html]
[test_lowDeviceStorage.html]
[test_lowDeviceStorageDuringUpdate.html]
[test_missingFile.html]
[test_missingManifest.html]
[test_noManifest.html]

View file

@ -1,91 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Low device storage</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/dom/tests/mochitest/ajax/offline/offlineTests.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
/**
* This test checks that an offline cache update scheduled *after* a low device
* storage situation appears is canceled. It basically does:
*
* 1. Notifies to the offline cache update service about a fake
* low device storage situation.
* 2. Schedules an update and observes for its notifications.
* 3. We are supposed to receive an error event notifying about the cancelation
* of the update because of the low storage situation.
* 4. Notifies to the offline cache update service that we've recovered from
* the low storage situation.
*/
var updateService = SpecialPowers.Cc['@mozilla.org/offlinecacheupdate-service;1']
.getService(Ci.nsIOfflineCacheUpdateService);
var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
.getService(SpecialPowers.Ci.nsIObserverService);
var errorReceived = false;
var systemPrincipal = SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal();
function finish() {
obs.notifyObservers(updateService, "disk-space-watcher", "free");
OfflineTest.teardownAndFinish();
}
if (OfflineTest.setup()) {
obs.notifyObservers(updateService, "disk-space-watcher", "full");
var updateObserver = {
updateStateChanged: function (aUpdate, aState) {
switch(aState) {
case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
errorReceived = true;
OfflineTest.ok(true, "Expected error. Update canceled");
break;
case Ci.nsIOfflineCacheUpdateObserver.STATE_FINISHED:
aUpdate.removeObserver(this);
OfflineTest.ok(errorReceived,
"Finished after receiving the expected error");
finish();
break;
case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
aUpdate.removeObserver(this);
OfflineTest.ok(false, "No update");
finish();
break;
case Ci.nsIOfflineCacheUpdateObserver.STATE_DOWNLOADING:
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMSTARTED:
case Ci.nsIOfflineCacheUpdateObserver.STATE_ITEMPROGRESS:
aUpdate.removeObserver(this);
OfflineTest.ok(false, "The update was supposed to be canceled");
finish();
break;
}
},
applicationCacheAvailable: function() {}
};
var manifest = "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/simpleManifest.cacheManifest";
var ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
var manifestURI = ioService.newURI(manifest, null, null);
var documentURI = ioService.newURI(document.documentURI, null, null);
var update = updateService.scheduleUpdate(manifestURI, documentURI, systemPrincipal, window);
update.addObserver(updateObserver, false);
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body>
</body>
</html>

View file

@ -1,58 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml" manifest="http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/simpleManifest.cacheManifest">
<head>
<title>Low device storage during update</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/dom/tests/mochitest/ajax/offline/offlineTests.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
/**
* This test checks that an offline cache update is canceled when a low device
* storage condition is detected during the update.
*/
var updateService = Cc['@mozilla.org/offlinecacheupdate-service;1']
.getService(Ci.nsIOfflineCacheUpdateService);
var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
.getService(SpecialPowers.Ci.nsIObserverService);
function finish() {
obs.notifyObservers(updateService, "disk-space-watcher", "free");
OfflineTest.teardownAndFinish();
}
function onError() {
OfflineTest.ok(true, "Expected error: Update canceled");
finish();
}
function onUnexpectedEvent() {
OfflineTest.ok(false, "The update was supposed to be canceled");
finish();
}
function onChecking() {
obs.notifyObservers(updateService, "disk-space-watcher", "full");
}
if (OfflineTest.setup()) {
applicationCache.onerror = OfflineTest.priv(onError);
applicationCache.onprogress = OfflineTest.priv(onUnexpectedEvent);
applicationCache.oncached = OfflineTest.priv(onUnexpectedEvent);
applicationCache.onchecking = OfflineTest.priv(onChecking);
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body>
</body>
</html>

View file

@ -47,6 +47,5 @@ skip-if = toolkit == 'android' #TIMED_OUT
skip-if = toolkit == 'android' #TIMED_OUT
[test_localStorageReplace.html]
skip-if = toolkit == 'android'
[test_lowDeviceStorage.html]
[test_storageConstructor.html]
[test_localStorageSessionPrefOverride.html]

View file

@ -1,76 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test localStorage usage while in a low device storage situation</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="localStorageCommon.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
/*
This test does the following:
- Stores an item in localStorage.
- Checks the stored value.
- Emulates a low device storage situation.
- Gets the stored item again.
- Removes the stored item.
- Fails storing a new value.
- Emulates recovering from a low device storage situation.
- Stores a new value.
- Checks the stored value.
*/
function lowDeviceStorage(lowStorage) {
var data = lowStorage ? "full" : "free";
os().notifyObservers(null, "disk-space-watcher", data);
}
function startTest() {
// Add a test item.
localStorage.setItem("item", "value");
is(localStorage.getItem("item"), "value", "getItem()");
// Emulates a low device storage situation.
lowDeviceStorage(true);
// Checks that we can still access to the stored item.
is(localStorage.getItem("item"), "value",
"getItem() during a device storage situation");
// Removes the stored item.
localStorage.removeItem("item");
is(localStorage.getItem("item"), null,
"getItem() after removing the item");
// Fails storing a new item.
try {
localStorage.setItem("newItem", "value");
ok(false, "Storing a new item is expected to fail");
} catch(e) {
ok(true, "Got an expected exception " + e);
} finally {
is(localStorage.getItem("newItem"), null,
"setItem while device storage is low");
}
// Emulates recovering from a low device storage situation.
lowDeviceStorage(false);
// Add a test item after recovering from the low device storage situation.
localStorage.setItem("newItem", "value");
is(localStorage.getItem("newItem"), "value",
"getItem() with available storage");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body onload="startTest();">
</body>
</html>