Bug 861920 - Avoid apps to write in its local storage while device free storage is low. r=honzab

This commit is contained in:
Fernando Jiménez 2013-05-10 16:20:05 +02:00
parent aa9e660583
commit 55022a3ba7
5 changed files with 64 additions and 4 deletions

View File

@ -194,6 +194,11 @@ 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

@ -9,6 +9,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/unused.h"
#include "nsIDiskSpaceWatcher.h"
namespace mozilla {
namespace dom {
@ -294,10 +295,10 @@ DOMStorageDBParent::ReleaseIPDLReference()
namespace { // anon
class SendScopesHavingDataRunnable : public nsRunnable
class SendInitialChildDataRunnable : public nsRunnable
{
public:
SendScopesHavingDataRunnable(DOMStorageDBParent* aParent)
SendInitialChildDataRunnable(DOMStorageDBParent* aParent)
: mParent(aParent)
{}
@ -315,6 +316,21 @@ private:
mozilla::unused << mParent->SendScopesHavingData(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) {
NS_WARNING("Could not get disk information from DiskSpaceWatcher");
return NS_OK;
}
bool lowDiskSpace = false;
diskSpaceWatcher->GetIsDiskFull(&lowDiskSpace);
if (lowDiskSpace) {
mozilla::unused << mParent->SendObserve(
nsDependentCString("low-disk-space"), EmptyCString());
}
return NS_OK;
}
@ -336,8 +352,8 @@ DOMStorageDBParent::DOMStorageDBParent()
// Cannot send directly from here since the channel
// is not completely built at this moment.
nsRefPtr<SendScopesHavingDataRunnable> r =
new SendScopesHavingDataRunnable(this);
nsRefPtr<SendInitialChildDataRunnable> r =
new SendInitialChildDataRunnable(this);
NS_DispatchToCurrentThread(r);
}

View File

@ -109,6 +109,7 @@ NS_IMPL_ISUPPORTS1(DOMStorageManager,
DOMStorageManager::DOMStorageManager(nsPIDOMStorage::StorageType aType)
: mType(aType)
, mLowDiskSpace(false)
{
mCaches.Init(10);
DOMStorageObserver* observer = DOMStorageObserver::Self();
@ -566,6 +567,22 @@ DOMStorageManager::Observe(const char* aTopic, const nsACString& aScopePrefix)
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

@ -87,6 +87,12 @@ private:
nsTHashtable<DOMStorageCacheHashKey> mCaches;
const nsPIDOMStorage::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; };
static PLDHashOperator ClearCacheEnumerator(DOMStorageCacheHashKey* aCache,
void* aClosure);

View File

@ -68,6 +68,9 @@ 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);
@ -300,6 +303,19 @@ DOMStorageObserver::Observe(nsISupports* aSubject,
return NS_OK;
}
if (!strcmp(aTopic, "disk-space-watcher")) {
printf_stderr("******## receive disk-space-watcher\n");
if (NS_LITERAL_STRING("full").Equals(aData)) {
printf_stderr("******## got full\n");
Notify("low-disk-space");
} else if (NS_LITERAL_STRING("free").Equals(aData)) {
printf_stderr("******## got free\n");
Notify("no-low-disk-space");
}
return NS_OK;
}
#ifdef DOM_STORAGE_TESTS
if (!strcmp(aTopic, "domstorage-test-flush-force")) {
DOMStorageDBBridge* db = DOMStorageCache::GetDatabase();