Bug 961049 - Part 4: QuotaManager on PBackground core changes; r=baku

This commit is contained in:
Jan Varga 2015-11-22 10:43:55 +01:00
parent 6abef8f019
commit 46c99e3a1c
35 changed files with 3730 additions and 743 deletions

View File

@ -5,7 +5,7 @@
Components.utils.import("resource:///modules/SitePermissions.jsm");
Components.utils.import("resource://gre/modules/BrowserUtils.jsm");
const nsIQuotaManager = Components.interfaces.nsIQuotaManager;
const nsIQuotaManagerService = Components.interfaces.nsIQuotaManagerService;
var gPermURI;
var gUsageRequest;
@ -186,13 +186,15 @@ function initIndexedDBRow()
row.appendChild(extras);
var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"]
.getService(nsIQuotaManager);
var quotaManagerService =
Components.classes["@mozilla.org/dom/quota-manager-service;1"]
.getService(nsIQuotaManagerService);
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.createCodebasePrincipal(gPermURI, {});
gUsageRequest =
quotaManager.getUsageForPrincipal(principal, onIndexedDBUsageCallback);
quotaManagerService.getUsageForPrincipal(principal,
onIndexedDBUsageCallback);
var status = document.getElementById("indexedDBStatus");
var button = document.getElementById("indexedDBClear");
@ -208,8 +210,8 @@ function onIndexedDBClear()
.getService(Components.interfaces.nsIScriptSecurityManager)
.createCodebasePrincipal(gPermURI, {});
Components.classes["@mozilla.org/dom/quota/manager;1"]
.getService(nsIQuotaManager)
Components.classes["@mozilla.org/dom/quota-manager-service;1"]
.getService(nsIQuotaManagerService)
.clearStoragesForPrincipal(principal);
Components.classes["@mozilla.org/serviceworkers/manager;1"]
@ -220,14 +222,14 @@ function onIndexedDBClear()
initIndexedDBRow();
}
function onIndexedDBUsageCallback(principal, usage, fileUsage)
function onIndexedDBUsageCallback(request)
{
let uri = principal.URI;
let uri = request.principal.URI;
if (!uri.equals(gPermURI)) {
throw new Error("Callback received for bad URI: " + uri);
}
if (usage) {
if (request.usage) {
if (!("DownloadUtils" in window)) {
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
}
@ -237,7 +239,7 @@ function onIndexedDBUsageCallback(principal, usage, fileUsage)
status.value =
gBundle.getFormattedString("indexedDBUsage",
DownloadUtils.convertByteUnits(usage));
DownloadUtils.convertByteUnits(request.usage));
status.removeAttribute("hidden");
button.removeAttribute("hidden");
}

View File

@ -69,7 +69,7 @@
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/dom/PresentationParent.h"
#include "mozilla/dom/PPresentationParent.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/quota/QuotaManagerService.h"
#include "mozilla/dom/telephony/TelephonyParent.h"
#include "mozilla/dom/time/DateCacheCleaner.h"
#include "mozilla/dom/voicemail/VoicemailParent.h"
@ -1795,10 +1795,10 @@ ContentParent::ShutDownProcess(ShutDownMethod aMethod)
return;
}
using mozilla::dom::quota::QuotaManager;
using mozilla::dom::quota::QuotaManagerService;
if (QuotaManager* quotaManager = QuotaManager::Get()) {
quotaManager->AbortOperationsForProcess(mChildID);
if (QuotaManagerService* quotaManagerService = QuotaManagerService::Get()) {
quotaManagerService->AbortOperationsForProcess(mChildID);
}
// If Close() fails with an error, we'll end up back in this function, but

268
dom/quota/ActorsChild.cpp Normal file
View File

@ -0,0 +1,268 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ActorsChild.h"
#include "QuotaManagerService.h"
#include "QuotaRequests.h"
namespace mozilla {
namespace dom {
namespace quota {
/*******************************************************************************
* QuotaChild
******************************************************************************/
QuotaChild::QuotaChild(QuotaManagerService* aService)
: mService(aService)
#ifdef DEBUG
, mOwningThread(NS_GetCurrentThread())
#endif
{
AssertIsOnOwningThread();
MOZ_ASSERT(aService);
MOZ_COUNT_CTOR(quota::QuotaChild);
}
QuotaChild::~QuotaChild()
{
AssertIsOnOwningThread();
MOZ_COUNT_DTOR(quota::QuotaChild);
}
#ifdef DEBUG
void
QuotaChild::AssertIsOnOwningThread() const
{
MOZ_ASSERT(mOwningThread);
bool current;
MOZ_ASSERT(NS_SUCCEEDED(mOwningThread->IsOnCurrentThread(&current)));
MOZ_ASSERT(current);
}
#endif // DEBUG
void
QuotaChild::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsOnOwningThread();
if (mService) {
mService->ClearBackgroundActor();
#ifdef DEBUG
mService = nullptr;
#endif
}
}
PQuotaUsageRequestChild*
QuotaChild::AllocPQuotaUsageRequestChild(const UsageRequestParams& aParams)
{
AssertIsOnOwningThread();
MOZ_CRASH("PQuotaUsageRequestChild actors should be manually constructed!");
}
bool
QuotaChild::DeallocPQuotaUsageRequestChild(PQuotaUsageRequestChild* aActor)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aActor);
delete static_cast<QuotaUsageRequestChild*>(aActor);
return true;
}
PQuotaRequestChild*
QuotaChild::AllocPQuotaRequestChild(const RequestParams& aParams)
{
AssertIsOnOwningThread();
MOZ_CRASH("PQuotaRequestChild actors should be manually constructed!");
}
bool
QuotaChild::DeallocPQuotaRequestChild(PQuotaRequestChild* aActor)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aActor);
delete static_cast<QuotaRequestChild*>(aActor);
return true;
}
/*******************************************************************************
* QuotaUsageRequestChild
******************************************************************************/
QuotaUsageRequestChild::QuotaUsageRequestChild(UsageRequest* aRequest)
: mRequest(aRequest)
{
AssertIsOnOwningThread();
MOZ_COUNT_CTOR(quota::QuotaUsageRequestChild);
}
QuotaUsageRequestChild::~QuotaUsageRequestChild()
{
// Can't assert owning thread here because the request is cleared.
MOZ_COUNT_DTOR(quota::QuotaUsageRequestChild);
}
#ifdef DEBUG
void
QuotaUsageRequestChild::AssertIsOnOwningThread() const
{
MOZ_ASSERT(mRequest);
mRequest->AssertIsOnOwningThread();
}
#endif // DEBUG
void
QuotaUsageRequestChild::HandleResponse(nsresult aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(NS_FAILED(aResponse));
MOZ_ASSERT(mRequest);
mRequest->SetError(aResponse);
}
void
QuotaUsageRequestChild::HandleResponse(const UsageResponse& aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
mRequest->SetResult(aResponse.usage(), aResponse.fileUsage());
}
void
QuotaUsageRequestChild::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsOnOwningThread();
if (mRequest) {
mRequest->ClearBackgroundActor();
#ifdef DEBUG
mRequest = nullptr;
#endif
}
}
bool
QuotaUsageRequestChild::Recv__delete__(const UsageRequestResponse& aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
switch (aResponse.type()) {
case UsageRequestResponse::Tnsresult:
HandleResponse(aResponse.get_nsresult());
break;
case UsageRequestResponse::TUsageResponse:
HandleResponse(aResponse.get_UsageResponse());
break;
default:
MOZ_CRASH("Unknown response type!");
}
return true;
}
/*******************************************************************************
* QuotaRequestChild
******************************************************************************/
QuotaRequestChild::QuotaRequestChild(Request* aRequest)
: mRequest(aRequest)
{
AssertIsOnOwningThread();
MOZ_COUNT_CTOR(quota::QuotaRequestChild);
}
QuotaRequestChild::~QuotaRequestChild()
{
AssertIsOnOwningThread();
MOZ_COUNT_DTOR(quota::QuotaRequestChild);
}
#ifdef DEBUG
void
QuotaRequestChild::AssertIsOnOwningThread() const
{
MOZ_ASSERT(mRequest);
mRequest->AssertIsOnOwningThread();
}
#endif // DEBUG
void
QuotaRequestChild::HandleResponse(nsresult aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(NS_FAILED(aResponse));
MOZ_ASSERT(mRequest);
mRequest->SetError(aResponse);
}
void
QuotaRequestChild::HandleResponse()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
mRequest->SetResult();
}
void
QuotaRequestChild::ActorDestroy(ActorDestroyReason aWhy)
{
AssertIsOnOwningThread();
}
bool
QuotaRequestChild::Recv__delete__(const RequestResponse& aResponse)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
switch (aResponse.type()) {
case RequestResponse::Tnsresult:
HandleResponse(aResponse.get_nsresult());
break;
case RequestResponse::TClearOriginResponse:
case RequestResponse::TClearAppResponse:
case RequestResponse::TClearAllResponse:
case RequestResponse::TResetAllResponse:
HandleResponse();
break;
default:
MOZ_CRASH("Unknown response type!");
}
return true;
}
} // namespace quota
} // namespace dom
} // namespace mozilla

153
dom/quota/ActorsChild.h Normal file
View File

@ -0,0 +1,153 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_quota_ActorsChild_h
#define mozilla_dom_quota_ActorsChild_h
#include "mozilla/dom/quota/PQuotaChild.h"
#include "mozilla/dom/quota/PQuotaRequestChild.h"
#include "mozilla/dom/quota/PQuotaUsageRequestChild.h"
namespace mozilla {
namespace ipc {
class BackgroundChildImpl;
} // namespace ipc
namespace dom {
namespace quota {
class QuotaManagerService;
class Request;
class UsageRequest;
class QuotaChild final
: public PQuotaChild
{
friend class mozilla::ipc::BackgroundChildImpl;
friend class QuotaManagerService;
QuotaManagerService* mService;
#ifdef DEBUG
nsCOMPtr<nsIEventTarget> mOwningThread;
#endif
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// Only created by QuotaManagerService.
explicit QuotaChild(QuotaManagerService* aService);
// Only destroyed by mozilla::ipc::BackgroundChildImpl.
~QuotaChild();
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual PQuotaUsageRequestChild*
AllocPQuotaUsageRequestChild(const UsageRequestParams& aParams) override;
virtual bool
DeallocPQuotaUsageRequestChild(PQuotaUsageRequestChild* aActor) override;
virtual PQuotaRequestChild*
AllocPQuotaRequestChild(const RequestParams& aParams) override;
virtual bool
DeallocPQuotaRequestChild(PQuotaRequestChild* aActor) override;
};
class QuotaUsageRequestChild final
: public PQuotaUsageRequestChild
{
friend class QuotaChild;
friend class QuotaManagerService;
RefPtr<UsageRequest> mRequest;
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// Only created by QuotaManagerService.
explicit QuotaUsageRequestChild(UsageRequest* aRequest);
// Only destroyed by QuotaChild.
~QuotaUsageRequestChild();
void
HandleResponse(nsresult aResponse);
void
HandleResponse(const UsageResponse& aResponse);
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool
Recv__delete__(const UsageRequestResponse& aResponse) override;
};
class QuotaRequestChild final
: public PQuotaRequestChild
{
friend class QuotaChild;
friend class QuotaManagerService;
RefPtr<Request> mRequest;
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// Only created by QuotaManagerService.
explicit QuotaRequestChild(Request* aRequest);
// Only destroyed by QuotaChild.
~QuotaRequestChild();
void
HandleResponse(nsresult aResponse);
void
HandleResponse();
// IPDL methods are only called by IPDL.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool
Recv__delete__(const RequestResponse& aResponse) override;
};
} // namespace quota
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_quota_ActorsChild_h

File diff suppressed because it is too large Load Diff

26
dom/quota/ActorsParent.h Normal file
View File

@ -0,0 +1,26 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_quota_ActorsParent_h
#define mozilla_dom_quota_ActorsParent_h
namespace mozilla {
namespace dom {
namespace quota {
class PQuotaParent;
PQuotaParent*
AllocPQuotaParent();
bool
DeallocPQuotaParent(PQuotaParent* aActor);
} // namespace quota
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_quota_ActorsParent_h

View File

@ -111,7 +111,7 @@ public:
virtual void
ReleaseIOThreadObjects() = 0;
// Methods which are called on the main thred.
// Methods which are called on the background thred.
virtual void
AbortOperations(const nsACString& aOrigin) = 0;
@ -119,7 +119,10 @@ public:
AbortOperationsForProcess(ContentParentId aContentParentId) = 0;
virtual void
PerformIdleMaintenance() = 0;
StartIdleMaintenance() = 0;
virtual void
StopIdleMaintenance() = 0;
virtual void
ShutdownWorkThreads() = 0;

View File

@ -63,6 +63,27 @@ public:
return mType;
}
void
SetFromOrigin(const nsACString& aOrigin)
{
Assign(aOrigin);
mType = eOrigin;
}
void
SetFromPattern(const nsACString& aPattern)
{
Assign(aPattern);
mType = ePattern;
}
void
SetFromNull()
{
SetIsVoid(true);
mType = eNull;
}
private:
OriginScope(const nsACString& aString, Type aType)
: nsCString(aString), mType(aType)
@ -71,7 +92,7 @@ private:
bool
operator==(const OriginScope& aOther) = delete;
const Type mType;
Type mType;
};
END_QUOTA_NAMESPACE

80
dom/quota/PQuota.ipdl Normal file
View File

@ -0,0 +1,80 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBackground;
include protocol PQuotaRequest;
include protocol PQuotaUsageRequest;
include PBackgroundSharedTypes;
include "mozilla/dom/quota/SerializationHelpers.h";
using mozilla::dom::quota::PersistenceType
from "mozilla/dom/quota/PersistenceType.h";
namespace mozilla {
namespace dom {
namespace quota {
struct UsageParams
{
PrincipalInfo principalInfo;
};
union UsageRequestParams
{
UsageParams;
};
struct ClearOriginParams
{
PrincipalInfo principalInfo;
PersistenceType persistenceType;
bool persistenceTypeIsExplicit;
};
struct ClearAppParams
{
uint32_t appId;
bool browserOnly;
};
struct ClearAllParams
{
};
struct ResetAllParams
{
};
union RequestParams
{
ClearOriginParams;
ClearAppParams;
ClearAllParams;
ResetAllParams;
};
protocol PQuota
{
manager PBackground;
manages PQuotaRequest;
manages PQuotaUsageRequest;
parent:
__delete__();
PQuotaUsageRequest(UsageRequestParams params);
PQuotaRequest(RequestParams params);
StartIdleMaintenance();
StopIdleMaintenance();
};
} // namespace quota
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,46 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PQuota;
namespace mozilla {
namespace dom {
namespace quota {
struct ClearOriginResponse
{
};
struct ClearAppResponse
{
};
struct ClearAllResponse
{
};
struct ResetAllResponse
{
};
union RequestResponse
{
nsresult;
ClearOriginResponse;
ClearAppResponse;
ClearAllResponse;
ResetAllResponse;
};
protocol PQuotaRequest
{
manager PQuota;
child:
__delete__(RequestResponse response);
};
} // namespace quota
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PQuota;
namespace mozilla {
namespace dom {
namespace quota {
struct UsageResponse
{
uint64_t usage;
uint64_t fileUsage;
};
union UsageRequestResponse
{
nsresult;
UsageResponse;
};
protocol PQuotaUsageRequest
{
manager PQuota;
parent:
Cancel();
child:
__delete__(UsageRequestResponse response);
};
} // namespace quota
} // namespace dom
} // namespace mozilla

View File

@ -30,8 +30,33 @@
NS_WARNING(str.get()); \
} while (0)
class nsIEventTarget;
BEGIN_QUOTA_NAMESPACE
class BackgroundThreadObject
{
protected:
nsCOMPtr<nsIEventTarget> mOwningThread;
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
nsIEventTarget*
OwningThread() const;
protected:
BackgroundThreadObject();
explicit BackgroundThreadObject(nsIEventTarget* aOwningThread);
};
void
AssertIsOnIOThread();

View File

@ -9,9 +9,6 @@
#include "QuotaCommon.h"
#include "nsIObserver.h"
#include "nsIQuotaManager.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/Mutex.h"
@ -24,6 +21,7 @@
#define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
class nsIEventTarget;
class nsIPrincipal;
class nsIThread;
class nsITimer;
@ -31,12 +29,6 @@ class nsIURI;
class nsPIDOMWindow;
class nsIRunnable;
namespace mozilla {
namespace dom {
class OptionalContentId;
} // namespace dom
} // namespace mozilla
BEGIN_QUOTA_NAMESPACE
class DirectoryLockImpl;
@ -56,10 +48,8 @@ public:
Release() = 0;
};
// nsISupports is needed for nsMainThreadPtrHandle<DirectoryLock>
// XXX RemoveMe once bug 1164581 gets fixed.
class DirectoryLock
: public nsISupports
: public RefCountedObject
{
friend class DirectoryLockImpl;
@ -101,8 +91,8 @@ struct OriginParams
bool mIsApp;
};
class QuotaManager final : public nsIQuotaManager,
public nsIObserver
class QuotaManager final
: public BackgroundThreadObject
{
friend class DirectoryLockImpl;
friend class GroupInfo;
@ -120,24 +110,26 @@ class QuotaManager final : public nsIQuotaManager,
nsTArray<DirectoryLockImpl*>> DirectoryLockTable;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIQUOTAMANAGER
NS_DECL_NSIOBSERVER
class CreateRunnable;
private:
class ShutdownRunnable;
class ShutdownObserver;
public:
NS_INLINE_DECL_REFCOUNTING(QuotaManager)
static const bool kRunningXPCShellTests;
static const char kReplaceChars[];
// Returns a non-owning reference.
static QuotaManager*
GetOrCreate();
static void
GetOrCreate(nsIRunnable* aCallback);
// Returns a non-owning reference.
static QuotaManager*
Get();
// Returns an owning reference! No one should call this but the factory.
static QuotaManager*
FactoryCreate();
// Returns true if we've begun the shutdown process.
static bool IsShuttingDown();
@ -261,6 +253,26 @@ public:
void
ResetOrClearCompleted();
void
StartIdleMaintenance()
{
AssertIsOnOwningThread();
for (auto& client : mClients) {
client->StartIdleMaintenance();
}
}
void
StopIdleMaintenance()
{
AssertIsOnOwningThread();
for (auto& client : mClients) {
client->StopIdleMaintenance();
}
}
void
AssertCurrentThreadOwnsQuotaMutex()
{
@ -372,7 +384,10 @@ private:
virtual ~QuotaManager();
nsresult
Init();
Init(const nsAString& aBaseDirPath);
void
Shutdown();
already_AddRefed<DirectoryLockImpl>
CreateDirectoryLock(Nullable<PersistenceType> aPersistenceType,
@ -429,9 +444,6 @@ private:
int64_t aAccessTime,
nsIFile* aDirectory);
nsresult
ClearStoragesForApp(uint32_t aAppId, bool aBrowserOnly);
void
CheckTemporaryStorageLimits();
@ -461,6 +473,9 @@ private:
const nsACString& aOrigin,
nsAutoCString& _retval);
static void
ShutdownTimerCallback(nsITimer* aTimer, void* aClosure);
mozilla::Mutex mQuotaMutex;
nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;

View File

@ -0,0 +1,823 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "QuotaManagerService.h"
#include "ActorsChild.h"
#include "mozIApplicationClearPrivateDataParams.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Hal.h"
#include "mozilla/Preferences.h"
#include "mozilla/unused.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsIIdleService.h"
#include "nsIIPCBackgroundChildCreateCallback.h"
#include "nsIObserverService.h"
#include "nsIScriptSecurityManager.h"
#include "nsXULAppAPI.h"
#include "QuotaManager.h"
#include "QuotaRequests.h"
#define PROFILE_BEFORE_CHANGE_OBSERVER_ID "profile-before-change"
namespace mozilla {
namespace dom {
namespace quota {
using namespace mozilla::ipc;
namespace {
// Preference that is used to enable testing features.
const char kTestingPref[] = "dom.quotaManager.testing";
const char kIdleServiceContractId[] = "@mozilla.org/widget/idleservice;1";
// The number of seconds we will wait after receiving the idle-daily
// notification before beginning maintenance.
const uint32_t kIdleObserverTimeSec = 1;
mozilla::StaticRefPtr<QuotaManagerService> gQuotaManagerService;
mozilla::Atomic<bool> gInitialized(false);
mozilla::Atomic<bool> gClosed(false);
mozilla::Atomic<bool> gTestingMode(false);
void
TestingPrefChangedCallback(const char* aPrefName,
void* aClosure)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!strcmp(aPrefName, kTestingPref));
MOZ_ASSERT(!aClosure);
gTestingMode = Preferences::GetBool(aPrefName);
}
class AbortOperationsRunnable final
: public nsRunnable
{
ContentParentId mContentParentId;
public:
explicit AbortOperationsRunnable(ContentParentId aContentParentId)
: mContentParentId(aContentParentId)
{ }
private:
NS_DECL_NSIRUNNABLE
};
} // namespace
class QuotaManagerService::BackgroundCreateCallback final
: public nsIIPCBackgroundChildCreateCallback
{
RefPtr<QuotaManagerService> mService;
public:
explicit
BackgroundCreateCallback(QuotaManagerService* aService)
: mService(aService)
{
MOZ_ASSERT(aService);
}
NS_DECL_ISUPPORTS
private:
~BackgroundCreateCallback()
{ }
NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
};
class QuotaManagerService::PendingRequestInfo
{
protected:
RefPtr<RequestBase> mRequest;
public:
explicit PendingRequestInfo(RequestBase* aRequest)
: mRequest(aRequest)
{ }
virtual ~PendingRequestInfo()
{ }
RequestBase*
GetRequest() const
{
return mRequest;
}
virtual nsresult
InitiateRequest(QuotaChild* aActor) = 0;
};
class QuotaManagerService::UsageRequestInfo
: public PendingRequestInfo
{
UsageRequestParams mParams;
public:
UsageRequestInfo(UsageRequest* aRequest,
const UsageRequestParams& aParams)
: PendingRequestInfo(aRequest)
, mParams(aParams)
{
MOZ_ASSERT(aRequest);
MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
}
virtual nsresult
InitiateRequest(QuotaChild* aActor) override;
};
class QuotaManagerService::RequestInfo
: public PendingRequestInfo
{
RequestParams mParams;
public:
RequestInfo(Request* aRequest,
const RequestParams& aParams)
: PendingRequestInfo(aRequest)
, mParams(aParams)
{
MOZ_ASSERT(aRequest);
MOZ_ASSERT(aParams.type() != RequestParams::T__None);
}
virtual nsresult
InitiateRequest(QuotaChild* aActor) override;
};
class QuotaManagerService::IdleMaintenanceInfo
: public PendingRequestInfo
{
const bool mStart;
public:
explicit IdleMaintenanceInfo(bool aStart)
: PendingRequestInfo(nullptr)
, mStart(aStart)
{ }
virtual nsresult
InitiateRequest(QuotaChild* aActor) override;
};
QuotaManagerService::QuotaManagerService()
: mBackgroundActor(nullptr)
, mBackgroundActorFailed(false)
, mIdleObserverRegistered(false)
{
MOZ_ASSERT(NS_IsMainThread());
}
QuotaManagerService::~QuotaManagerService()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mIdleObserverRegistered);
}
// static
QuotaManagerService*
QuotaManagerService::GetOrCreate()
{
MOZ_ASSERT(NS_IsMainThread());
if (gClosed) {
MOZ_ASSERT(false, "Calling GetOrCreate() after shutdown!");
return nullptr;
}
if (!gQuotaManagerService) {
RefPtr<QuotaManagerService> instance(new QuotaManagerService());
nsresult rv = instance->Init();
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
if (gInitialized.exchange(true)) {
MOZ_ASSERT(false, "Initialized more than once?!");
}
gQuotaManagerService = instance;
ClearOnShutdown(&gQuotaManagerService);
}
return gQuotaManagerService;
}
// static
QuotaManagerService*
QuotaManagerService::Get()
{
// Does not return an owning reference.
return gQuotaManagerService;
}
// static
QuotaManagerService*
QuotaManagerService::FactoryCreate()
{
// Returns a raw pointer that carries an owning reference! Lame, but the
// singleton factory macros force this.
QuotaManagerService* quotaManagerService = GetOrCreate();
NS_IF_ADDREF(quotaManagerService);
return quotaManagerService;
}
void
QuotaManagerService::ClearBackgroundActor()
{
MOZ_ASSERT(NS_IsMainThread());
mBackgroundActor = nullptr;
}
void
QuotaManagerService::NoteLiveManager(QuotaManager* aManager)
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aManager);
mBackgroundThread = aManager->OwningThread();
}
void
QuotaManagerService::NoteFinishedManager()
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
mBackgroundThread = nullptr;
}
void
QuotaManagerService::AbortOperationsForProcess(ContentParentId aContentParentId)
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
if (!mBackgroundThread) {
return;
}
RefPtr<AbortOperationsRunnable> runnable =
new AbortOperationsRunnable(aContentParentId);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
mBackgroundThread->Dispatch(runnable, NS_DISPATCH_NORMAL)));
}
nsresult
QuotaManagerService::Init()
{
MOZ_ASSERT(NS_IsMainThread());
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (NS_WARN_IF(!observerService)) {
return NS_ERROR_FAILURE;
}
nsresult rv = observerService->AddObserver(this,
PROFILE_BEFORE_CHANGE_OBSERVER_ID,
false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
Preferences::RegisterCallbackAndCall(TestingPrefChangedCallback,
kTestingPref);
return NS_OK;
}
void
QuotaManagerService::Destroy()
{
// Setting the closed flag prevents the service from being recreated.
// Don't set it though if there's no real instance created.
if (gInitialized && gClosed.exchange(true)) {
MOZ_ASSERT(false, "Shutdown more than once?!");
}
Preferences::UnregisterCallback(TestingPrefChangedCallback, kTestingPref);
delete this;
}
nsresult
QuotaManagerService::InitiateRequest(nsAutoPtr<PendingRequestInfo>& aInfo)
{
// Nothing can be done here if we have previously failed to create a
// background actor.
if (mBackgroundActorFailed) {
return NS_ERROR_FAILURE;
}
if (!mBackgroundActor && mPendingRequests.IsEmpty()) {
// We need to start the sequence to create a background actor for this
// thread.
RefPtr<BackgroundCreateCallback> cb = new BackgroundCreateCallback(this);
if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) {
return NS_ERROR_FAILURE;
}
}
// If we already have a background actor then we can start this request now.
if (mBackgroundActor) {
nsresult rv = aInfo->InitiateRequest(mBackgroundActor);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
mPendingRequests.AppendElement(aInfo.forget());
}
return NS_OK;
}
nsresult
QuotaManagerService::BackgroundActorCreated(PBackgroundChild* aBackgroundActor)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBackgroundActor);
MOZ_ASSERT(!mBackgroundActor);
MOZ_ASSERT(!mBackgroundActorFailed);
{
QuotaChild* actor = new QuotaChild(this);
mBackgroundActor =
static_cast<QuotaChild*>(aBackgroundActor->SendPQuotaConstructor(actor));
}
if (NS_WARN_IF(!mBackgroundActor)) {
BackgroundActorFailed();
return NS_ERROR_FAILURE;
}
nsresult rv = NS_OK;
for (uint32_t index = 0, count = mPendingRequests.Length();
index < count;
index++) {
nsAutoPtr<PendingRequestInfo> info(mPendingRequests[index].forget());
nsresult rv2 = info->InitiateRequest(mBackgroundActor);
// Warn for every failure, but just return the first failure if there are
// multiple failures.
if (NS_WARN_IF(NS_FAILED(rv2)) && NS_SUCCEEDED(rv)) {
rv = rv2;
}
}
mPendingRequests.Clear();
return rv;
}
void
QuotaManagerService::BackgroundActorFailed()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mPendingRequests.IsEmpty());
MOZ_ASSERT(!mBackgroundActor);
MOZ_ASSERT(!mBackgroundActorFailed);
mBackgroundActorFailed = true;
for (uint32_t index = 0, count = mPendingRequests.Length();
index < count;
index++) {
nsAutoPtr<PendingRequestInfo> info(mPendingRequests[index].forget());
RequestBase* request = info->GetRequest();
if (request) {
request->SetError(NS_ERROR_FAILURE);
}
}
mPendingRequests.Clear();
}
void
QuotaManagerService::PerformIdleMaintenance()
{
using namespace mozilla::hal;
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
// If we're running on battery power then skip all idle maintenance since we
// would otherwise be doing lots of disk I/O.
BatteryInformation batteryInfo;
#ifdef MOZ_WIDGET_ANDROID
// Android XPCShell doesn't load the AndroidBridge that is needed to make
// GetCurrentBatteryInformation work...
if (!QuotaManager::kRunningXPCShellTests)
#endif
{
GetCurrentBatteryInformation(&batteryInfo);
}
// If we're running XPCShell because we always want to be able to test this
// code so pretend that we're always charging.
if (QuotaManager::kRunningXPCShellTests) {
batteryInfo.level() = 100;
batteryInfo.charging() = true;
}
if (NS_WARN_IF(!batteryInfo.charging())) {
return;
}
if (QuotaManager::kRunningXPCShellTests) {
// We don't want user activity to impact this code if we're running tests.
Unused << Observe(nullptr, OBSERVER_TOPIC_IDLE, nullptr);
} else if (!mIdleObserverRegistered) {
nsCOMPtr<nsIIdleService> idleService =
do_GetService(kIdleServiceContractId);
MOZ_ASSERT(idleService);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
idleService->AddIdleObserver(this, kIdleObserverTimeSec)));
mIdleObserverRegistered = true;
}
}
void
QuotaManagerService::RemoveIdleObserver()
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
if (mIdleObserverRegistered) {
nsCOMPtr<nsIIdleService> idleService =
do_GetService(kIdleServiceContractId);
MOZ_ASSERT(idleService);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
idleService->RemoveIdleObserver(this, kIdleObserverTimeSec)));
mIdleObserverRegistered = false;
}
}
NS_IMPL_ADDREF(QuotaManagerService)
NS_IMPL_RELEASE_WITH_DESTROY(QuotaManagerService, Destroy())
NS_IMPL_QUERY_INTERFACE(QuotaManagerService,
nsIQuotaManagerService,
nsIObserver)
NS_IMETHODIMP
QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
nsIQuotaUsageCallback* aCallback,
nsIQuotaUsageRequest** _retval)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(aCallback);
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
RefPtr<UsageRequest> request = new UsageRequest(aPrincipal, aCallback);
UsageParams params;
PrincipalInfo& principalInfo = params.principalInfo();
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
return NS_ERROR_UNEXPECTED;
}
nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::Clear(nsIQuotaRequest** _retval)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
if (NS_WARN_IF(!gTestingMode)) {
return NS_ERROR_UNEXPECTED;
}
RefPtr<Request> request = new Request();
ClearAllParams params;
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
nsresult rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::ClearStoragesForPrincipal(nsIPrincipal* aPrincipal,
const nsACString& aPersistenceType,
nsIQuotaRequest** _retval)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
RefPtr<Request> request = new Request(aPrincipal);
ClearOriginParams params;
PrincipalInfo& principalInfo = params.principalInfo();
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
return NS_ERROR_UNEXPECTED;
}
Nullable<PersistenceType> persistenceType;
rv = NullablePersistenceTypeFromText(aPersistenceType, &persistenceType);
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_INVALID_ARG;
}
if (persistenceType.IsNull()) {
params.persistenceTypeIsExplicit() = false;
} else {
params.persistenceType() = persistenceType.Value();
params.persistenceTypeIsExplicit() = true;
}
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::Reset(nsIQuotaRequest** _retval)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
if (NS_WARN_IF(!gTestingMode)) {
return NS_ERROR_UNEXPECTED;
}
RefPtr<Request> request = new Request();
ResetAllParams params;
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, params));
nsresult rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
if (!strcmp(aTopic, PROFILE_BEFORE_CHANGE_OBSERVER_ID)) {
RemoveIdleObserver();
return NS_OK;
}
if (!strcmp(aTopic, TOPIC_WEB_APP_CLEAR_DATA)) {
nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
do_QueryInterface(aSubject);
if (NS_WARN_IF(!params)) {
return NS_ERROR_UNEXPECTED;
}
uint32_t appId;
nsresult rv = params->GetAppId(&appId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool browserOnly;
rv = params->GetBrowserOnly(&browserOnly);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
RefPtr<Request> request = new Request();
ClearAppParams requestParams;
requestParams.appId() = appId;
requestParams.browserOnly() = browserOnly;
nsAutoPtr<PendingRequestInfo> info(new RequestInfo(request, requestParams));
rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY)) {
PerformIdleMaintenance();
return NS_OK;
}
if (!strcmp(aTopic, OBSERVER_TOPIC_IDLE)) {
nsAutoPtr<PendingRequestInfo> info(
new IdleMaintenanceInfo(/* aStart */ true));
nsresult rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
if (!strcmp(aTopic, OBSERVER_TOPIC_ACTIVE)) {
RemoveIdleObserver();
nsAutoPtr<PendingRequestInfo> info(
new IdleMaintenanceInfo(/* aStart */ false));
nsresult rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
MOZ_ASSERT_UNREACHABLE("Should never get here!");
return NS_OK;
}
NS_IMETHODIMP
AbortOperationsRunnable::Run()
{
AssertIsOnBackgroundThread();
if (QuotaManager::IsShuttingDown()) {
return NS_OK;
}
QuotaManager* quotaManager = QuotaManager::Get();
if (!quotaManager) {
return NS_OK;
}
quotaManager->AbortOperationsForProcess(mContentParentId);
return NS_OK;
}
NS_IMPL_ISUPPORTS(QuotaManagerService::BackgroundCreateCallback,
nsIIPCBackgroundChildCreateCallback)
void
QuotaManagerService::
BackgroundCreateCallback::ActorCreated(PBackgroundChild* aActor)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aActor);
MOZ_ASSERT(mService);
RefPtr<QuotaManagerService> service;
mService.swap(service);
service->BackgroundActorCreated(aActor);
}
void
QuotaManagerService::
BackgroundCreateCallback::ActorFailed()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mService);
RefPtr<QuotaManagerService> service;
mService.swap(service);
service->BackgroundActorFailed();
}
nsresult
QuotaManagerService::
UsageRequestInfo::InitiateRequest(QuotaChild* aActor)
{
MOZ_ASSERT(aActor);
auto request = static_cast<UsageRequest*>(mRequest.get());
auto actor = new QuotaUsageRequestChild(request);
if (!aActor->SendPQuotaUsageRequestConstructor(actor, mParams)) {
request->SetError(NS_ERROR_FAILURE);
return NS_ERROR_FAILURE;
}
request->SetBackgroundActor(actor);
return NS_OK;
}
nsresult
QuotaManagerService::
RequestInfo::InitiateRequest(QuotaChild* aActor)
{
MOZ_ASSERT(aActor);
auto request = static_cast<Request*>(mRequest.get());
auto actor = new QuotaRequestChild(request);
if (!aActor->SendPQuotaRequestConstructor(actor, mParams)) {
request->SetError(NS_ERROR_FAILURE);
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
QuotaManagerService::
IdleMaintenanceInfo::InitiateRequest(QuotaChild* aActor)
{
MOZ_ASSERT(aActor);
bool result;
if (mStart) {
result = aActor->SendStartIdleMaintenance();
} else {
result = aActor->SendStopIdleMaintenance();
}
if (!result) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
} // namespace quota
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,112 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_quota_QuotaManagerService_h
#define mozilla_dom_quota_QuotaManagerService_h
#include "mozilla/dom/ipc/IdType.h"
#include "nsIObserver.h"
#include "nsIQuotaManagerService.h"
#define QUOTAMANAGER_SERVICE_CONTRACTID \
"@mozilla.org/dom/quota-manager-service;1"
namespace mozilla {
namespace ipc {
class PBackgroundChild;
} // namespace ipc
namespace dom {
namespace quota {
class QuotaChild;
class QuotaManager;
class QuotaManagerService final
: public nsIQuotaManagerService
, public nsIObserver
{
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
class BackgroundCreateCallback;
class PendingRequestInfo;
class UsageRequestInfo;
class RequestInfo;
class IdleMaintenanceInfo;
nsCOMPtr<nsIEventTarget> mBackgroundThread;
nsTArray<nsAutoPtr<PendingRequestInfo>> mPendingRequests;
QuotaChild* mBackgroundActor;
bool mBackgroundActorFailed;
bool mIdleObserverRegistered;
public:
// Returns a non-owning reference.
static QuotaManagerService*
GetOrCreate();
// Returns a non-owning reference.
static QuotaManagerService*
Get();
// Returns an owning reference! No one should call this but the factory.
static QuotaManagerService*
FactoryCreate();
void
ClearBackgroundActor();
void
NoteLiveManager(QuotaManager* aManager);
void
NoteFinishedManager();
// Called when a process is being shot down. Aborts any running operations
// for the given process.
void
AbortOperationsForProcess(ContentParentId aContentParentId);
private:
QuotaManagerService();
~QuotaManagerService();
nsresult
Init();
void
Destroy();
nsresult
InitiateRequest(nsAutoPtr<PendingRequestInfo>& aInfo);
nsresult
BackgroundActorCreated(PBackgroundChild* aBackgroundActor);
void
BackgroundActorFailed();
void
PerformIdleMaintenance();
void
RemoveIdleObserver();
NS_DECL_ISUPPORTS
NS_DECL_NSIQUOTAMANAGERSERVICE
NS_DECL_NSIOBSERVER
};
} // namespace quota
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_quota_QuotaManagerService_h */

296
dom/quota/QuotaRequests.cpp Normal file
View File

@ -0,0 +1,296 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "QuotaRequests.h"
#include "ActorsChild.h"
#include "nsIQuotaCallbacks.h"
namespace mozilla {
namespace dom {
namespace quota {
RequestBase::RequestBase()
: mResultCode(NS_OK)
, mHaveResultOrErrorCode(false)
{
#ifdef DEBUG
mOwningThread = PR_GetCurrentThread();
#endif
AssertIsOnOwningThread();
}
RequestBase::RequestBase(nsIPrincipal* aPrincipal)
: mPrincipal(aPrincipal)
, mResultCode(NS_OK)
, mHaveResultOrErrorCode(false)
{
#ifdef DEBUG
mOwningThread = PR_GetCurrentThread();
#endif
AssertIsOnOwningThread();
}
#ifdef DEBUG
void
RequestBase::AssertIsOnOwningThread() const
{
MOZ_ASSERT(mOwningThread);
MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread);
}
#endif // DEBUG
void
RequestBase::SetError(nsresult aRv)
{
AssertIsOnOwningThread();
MOZ_ASSERT(mResultCode == NS_OK);
MOZ_ASSERT(!mHaveResultOrErrorCode);
mResultCode = aRv;
mHaveResultOrErrorCode = true;
FireCallback();
}
NS_IMPL_CYCLE_COLLECTION_0(RequestBase)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RequestBase)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(RequestBase)
NS_IMPL_CYCLE_COLLECTING_RELEASE(RequestBase)
NS_IMETHODIMP
RequestBase::GetPrincipal(nsIPrincipal** aPrincipal)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aPrincipal);
NS_IF_ADDREF(*aPrincipal = mPrincipal);
return NS_OK;
}
NS_IMETHODIMP
RequestBase::GetResultCode(nsresult* aResultCode)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aResultCode);
if (!mHaveResultOrErrorCode) {
return NS_ERROR_FAILURE;
}
*aResultCode = mResultCode;
return NS_OK;
}
UsageRequest::UsageRequest(nsIPrincipal* aPrincipal,
nsIQuotaUsageCallback* aCallback)
: RequestBase(aPrincipal)
, mCallback(aCallback)
, mUsage(0)
, mFileUsage(0)
, mBackgroundActor(nullptr)
, mCanceled(false)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(aCallback);
}
UsageRequest::~UsageRequest()
{
AssertIsOnOwningThread();
}
void
UsageRequest::SetBackgroundActor(QuotaUsageRequestChild* aBackgroundActor)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aBackgroundActor);
MOZ_ASSERT(!mBackgroundActor);
mBackgroundActor = aBackgroundActor;
if (mCanceled) {
mBackgroundActor->SendCancel();
}
}
void
UsageRequest::SetResult(uint64_t aUsage, uint64_t aFileUsage)
{
AssertIsOnOwningThread();
MOZ_ASSERT(!mHaveResultOrErrorCode);
mUsage = aUsage;
mFileUsage = aFileUsage;
mHaveResultOrErrorCode = true;
FireCallback();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(UsageRequest, RequestBase, mCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(UsageRequest)
NS_INTERFACE_MAP_ENTRY(nsIQuotaUsageRequest)
NS_INTERFACE_MAP_END_INHERITING(RequestBase)
NS_IMPL_ADDREF_INHERITED(UsageRequest, RequestBase)
NS_IMPL_RELEASE_INHERITED(UsageRequest, RequestBase)
NS_IMETHODIMP
UsageRequest::GetUsage(uint64_t* aUsage)
{
AssertIsOnOwningThread();
if (!mHaveResultOrErrorCode) {
return NS_ERROR_FAILURE;
}
*aUsage = mUsage;
return NS_OK;
}
NS_IMETHODIMP
UsageRequest::GetFileUsage(uint64_t* aFileUsage)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aFileUsage);
if (!mHaveResultOrErrorCode) {
return NS_ERROR_FAILURE;
}
*aFileUsage = mFileUsage;
return NS_OK;
}
NS_IMETHODIMP
UsageRequest::GetCallback(nsIQuotaUsageCallback** aCallback)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aCallback);
NS_IF_ADDREF(*aCallback = mCallback);
return NS_OK;
}
NS_IMETHODIMP
UsageRequest::SetCallback(nsIQuotaUsageCallback* aCallback)
{
AssertIsOnOwningThread();
mCallback = aCallback;
return NS_OK;
}
NS_IMETHODIMP
UsageRequest::Cancel()
{
AssertIsOnOwningThread();
if (mCanceled) {
NS_WARNING("Canceled more than once?!");
return NS_ERROR_UNEXPECTED;
}
if (mBackgroundActor) {
mBackgroundActor->SendCancel();
}
mCanceled = true;
return NS_OK;
}
void
UsageRequest::FireCallback()
{
AssertIsOnOwningThread();
MOZ_ASSERT(mCallback);
mCallback->OnUsageResult(this);
// Clean up.
mCallback = nullptr;
}
Request::Request()
{
AssertIsOnOwningThread();
}
Request::Request(nsIPrincipal* aPrincipal)
: RequestBase(aPrincipal)
{
AssertIsOnOwningThread();
}
Request::~Request()
{
AssertIsOnOwningThread();
}
void
Request::SetResult()
{
AssertIsOnOwningThread();
MOZ_ASSERT(!mHaveResultOrErrorCode);
mHaveResultOrErrorCode = true;
FireCallback();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(Request, RequestBase, mCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(Request)
NS_INTERFACE_MAP_ENTRY(nsIQuotaRequest)
NS_INTERFACE_MAP_END_INHERITING(RequestBase)
NS_IMPL_ADDREF_INHERITED(mozilla::dom::quota::Request, RequestBase)
NS_IMPL_RELEASE_INHERITED(mozilla::dom::quota::Request, RequestBase)
NS_IMETHODIMP
Request::GetCallback(nsIQuotaCallback** aCallback)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aCallback);
NS_IF_ADDREF(*aCallback = mCallback);
return NS_OK;
}
NS_IMETHODIMP
Request::SetCallback(nsIQuotaCallback* aCallback)
{
AssertIsOnOwningThread();
mCallback = aCallback;
return NS_OK;
}
void
Request::FireCallback()
{
AssertIsOnOwningThread();
if (mCallback) {
mCallback->OnComplete(this);
// Clean up.
mCallback = nullptr;
}
}
} // namespace quota
} // namespace dom
} // namespace mozilla

141
dom/quota/QuotaRequests.h Normal file
View File

@ -0,0 +1,141 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_quota_UsageRequest_h
#define mozilla_dom_quota_UsageRequest_h
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIQuotaRequests.h"
class nsIPrincipal;
class nsIQuotaCallback;
class nsIQuotaUsageCallback;
struct PRThread;
namespace mozilla {
namespace dom {
namespace quota {
class QuotaUsageRequestChild;
class RequestBase
: public nsIQuotaRequestBase
{
protected:
#ifdef DEBUG
PRThread* mOwningThread;
#endif
nsCOMPtr<nsIPrincipal> mPrincipal;
nsresult mResultCode;
bool mHaveResultOrErrorCode;
public:
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
void
SetError(nsresult aRv);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIQUOTAREQUESTBASE
NS_DECL_CYCLE_COLLECTION_CLASS(RequestBase)
protected:
RequestBase();
RequestBase(nsIPrincipal* aPrincipal);
virtual ~RequestBase()
{
AssertIsOnOwningThread();
}
virtual void
FireCallback() = 0;
};
class UsageRequest final
: public RequestBase
, public nsIQuotaUsageRequest
{
nsCOMPtr<nsIQuotaUsageCallback> mCallback;
uint64_t mUsage;
uint64_t mFileUsage;
QuotaUsageRequestChild* mBackgroundActor;
bool mCanceled;
public:
UsageRequest(nsIPrincipal* aPrincipal,
nsIQuotaUsageCallback* aCallback);
void
SetBackgroundActor(QuotaUsageRequestChild* aBackgroundActor);
void
ClearBackgroundActor()
{
AssertIsOnOwningThread();
mBackgroundActor = nullptr;
}
void
SetResult(uint64_t aUsage, uint64_t aFileUsage);
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_NSIQUOTAREQUESTBASE(RequestBase::)
NS_DECL_NSIQUOTAUSAGEREQUEST
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(UsageRequest, RequestBase)
private:
~UsageRequest();
virtual void
FireCallback() override;
};
class Request final
: public RequestBase
, public nsIQuotaRequest
{
nsCOMPtr<nsIQuotaCallback> mCallback;
public:
Request();
explicit Request(nsIPrincipal* aPrincipal);
void
SetResult();
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_NSIQUOTAREQUESTBASE(RequestBase::)
NS_DECL_NSIQUOTAREQUEST
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Request, RequestBase)
private:
~Request();
virtual void
FireCallback() override;
};
} // namespace quota
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_quota_UsageRequest_h

View File

@ -5,27 +5,38 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsIQuotaManager.idl',
'nsIQuotaRequest.idl',
'nsIUsageCallback.idl',
'nsIQuotaCallbacks.idl',
'nsIQuotaManagerService.idl',
'nsIQuotaRequests.idl',
]
XPIDL_MODULE = 'dom_quota'
EXPORTS.mozilla.dom.quota += [
'ActorsParent.h',
'Client.h',
'FileStreams.h',
'PersistenceType.h',
'QuotaCommon.h',
'QuotaManager.h',
'QuotaManagerService.h',
'QuotaObject.h',
'SerializationHelpers.h',
'UsageInfo.h',
]
UNIFIED_SOURCES += [
'ActorsChild.cpp',
'ActorsParent.cpp',
'FileStreams.cpp',
'QuotaManager.cpp',
'QuotaManagerService.cpp',
'QuotaRequests.cpp',
]
IPDL_SOURCES += [
'PQuota.ipdl',
'PQuotaRequest.ipdl',
'PQuotaUsageRequest.ipdl',
]
include('/ipc/chromium/chromium-config.mozbuild')

View File

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIQuotaRequest;
interface nsIQuotaUsageRequest;
[scriptable, function, uuid(c8a21a2a-17b9-4b63-ad95-e0fbcff5de18)]
interface nsIQuotaUsageCallback : nsISupports
{
void onUsageResult(in nsIQuotaUsageRequest aRequest);
};
[scriptable, function, uuid(a08a28e2-5a74-4c84-8070-ed45a07eb013)]
interface nsIQuotaCallback : nsISupports
{
void onComplete(in nsIQuotaRequest aRequest);
};

View File

@ -6,12 +6,13 @@
#include "nsISupports.idl"
interface nsIQuotaRequest;
interface nsIPrincipal;
interface nsIUsageCallback;
interface nsIQuotaRequest;
interface nsIQuotaUsageCallback;
interface nsIQuotaUsageRequest;
[scriptable, builtinclass, uuid(101cf53c-e7f3-4723-9f43-a23a85c8eda0)]
interface nsIQuotaManager : nsISupports
[scriptable, builtinclass, uuid(1b3d0a38-8151-4cf9-89fa-4f92c2ef0e7e)]
interface nsIQuotaManagerService : nsISupports
{
/**
* Schedules an asynchronous callback that will return the total amount of
@ -22,9 +23,9 @@ interface nsIQuotaManager : nsISupports
* @param aCallback
* The callback that will be called when the usage is available.
*/
nsIQuotaRequest
nsIQuotaUsageRequest
getUsageForPrincipal(in nsIPrincipal aPrincipal,
in nsIUsageCallback aCallback);
in nsIQuotaUsageCallback aCallback);
/**
* Removes all storages. The files may not be deleted immediately depending
@ -34,7 +35,7 @@ interface nsIQuotaManager : nsISupports
* If the dom.quotaManager.testing preference is not true the call will be
* a no-op.
*/
void
nsIQuotaRequest
clear();
/**
@ -44,7 +45,7 @@ interface nsIQuotaManager : nsISupports
* @param aPrincipal
* A principal for the origin whose storages are to be cleared.
*/
void
nsIQuotaRequest
clearStoragesForPrincipal(in nsIPrincipal aPrincipal,
[optional] in ACString aPersistenceType);
@ -57,6 +58,6 @@ interface nsIQuotaManager : nsISupports
* If the dom.quotaManager.testing preference is not true the call will be
* a no-op.
*/
void
nsIQuotaRequest
reset();
};

View File

@ -1,14 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
[scriptable, function, uuid(d96769ed-63ac-4070-ac5a-4b0e1728618a)]
interface nsIQuotaRequest : nsISupports
{
void
cancel();
};

View File

@ -0,0 +1,38 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIPrincipal;
interface nsIQuotaCallback;
interface nsIQuotaUsageCallback;
[scriptable, uuid(9af54222-0407-48fd-a4ab-9457c986fc49)]
interface nsIQuotaRequestBase : nsISupports
{
readonly attribute nsIPrincipal principal;
readonly attribute nsresult resultCode;
};
[scriptable, uuid(166e28e6-cf6d-4927-a6d7-b51bca9d3469)]
interface nsIQuotaUsageRequest : nsIQuotaRequestBase
{
readonly attribute unsigned long long usage;
readonly attribute unsigned long long fileUsage;
attribute nsIQuotaUsageCallback callback;
void
cancel();
};
[scriptable, uuid(22890e3e-ff25-4372-9684-d901060e2f6c)]
interface nsIQuotaRequest : nsIQuotaRequestBase
{
attribute nsIQuotaCallback callback;
};

View File

@ -1,17 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIPrincipal;
[scriptable, function, uuid(54b9f44f-533f-41ee-8fa8-86cc978125f0)]
interface nsIUsageCallback : nsISupports
{
void onUsageResult(in nsIPrincipal aPrincipal,
in unsigned long long aUsage,
in unsigned long long aFileUsage);
};

View File

@ -18,6 +18,7 @@
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/quota/PQuotaChild.h"
#include "mozilla/dom/MessagePortChild.h"
#include "mozilla/dom/NuwaChild.h"
#include "mozilla/ipc/PBackgroundTestChild.h"
@ -415,6 +416,21 @@ BackgroundChildImpl::DeallocPAsmJSCacheEntryChild(PAsmJSCacheEntryChild* aActor)
return true;
}
BackgroundChildImpl::PQuotaChild*
BackgroundChildImpl::AllocPQuotaChild()
{
MOZ_CRASH("PQuotaChild actor should be manually constructed!");
}
bool
BackgroundChildImpl::DeallocPQuotaChild(PQuotaChild* aActor)
{
MOZ_ASSERT(aActor);
delete aActor;
return true;
}
} // namespace ipc
} // namespace mozilla

View File

@ -145,6 +145,12 @@ protected:
virtual bool
DeallocPAsmJSCacheEntryChild(PAsmJSCacheEntryChild* aActor) override;
virtual PQuotaChild*
AllocPQuotaChild() override;
virtual bool
DeallocPQuotaChild(PQuotaChild* aActor) override;
};
class BackgroundChildImpl::ThreadLocal final

View File

@ -21,6 +21,7 @@
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/quota/ActorsParent.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/BackgroundUtils.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
@ -678,6 +679,25 @@ BackgroundParentImpl::DeallocPAsmJSCacheEntryParent(
return true;
}
BackgroundParentImpl::PQuotaParent*
BackgroundParentImpl::AllocPQuotaParent()
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
return mozilla::dom::quota::AllocPQuotaParent();
}
bool
BackgroundParentImpl::DeallocPQuotaParent(PQuotaParent* aActor)
{
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(aActor);
return mozilla::dom::quota::DeallocPQuotaParent(aActor);
}
} // namespace ipc
} // namespace mozilla

View File

@ -165,6 +165,12 @@ protected:
virtual bool
DeallocPAsmJSCacheEntryParent(PAsmJSCacheEntryParent* aActor) override;
virtual PQuotaParent*
AllocPQuotaParent() override;
virtual bool
DeallocPQuotaParent(PQuotaParent* aActor) override;
};
} // namespace ipc

View File

@ -14,6 +14,7 @@ include protocol PFileDescriptorSet;
include protocol PMessagePort;
include protocol PCameras;
include protocol PNuwa;
include protocol PQuota;
include protocol PServiceWorkerManager;
include protocol PUDPSocket;
include protocol PVsync;
@ -50,6 +51,7 @@ sync protocol PBackground
manages PMessagePort;
manages PCameras;
manages PNuwa;
manages PQuota;
manages PServiceWorkerManager;
manages PUDPSocket;
manages PVsync;
@ -84,6 +86,8 @@ parent:
WriteParams write,
PrincipalInfo principalInfo);
PQuota();
child:
PCache();
PCacheStreamControl();

View File

@ -75,7 +75,7 @@
{ 0x3160e271, 0x138d, 0x4cc7, { 0x9d, 0x63, 0x64, 0x29, 0xf1, 0x69, 0x57, 0xc7 } }
// {5a75c25a-5e7e-4d90-8f7c-07eb15cc0aa8}
#define QUOTA_MANAGER_CID \
#define QUOTAMANAGER_SERVICE_CID \
{ 0x5a75c25a, 0x5e7e, 0x4d90, { 0x8f, 0x7c, 0x07, 0xeb, 0x15, 0xcc, 0x0a, 0xa8 } }
// {c74bde32-bcc7-4840-8430-c733351b212a}

View File

@ -87,7 +87,7 @@
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMRequest.h"
#include "mozilla/dom/network/UDPSocketChild.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/quota/QuotaManagerService.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
#include "mozilla/dom/workers/WorkerDebuggerManager.h"
#include "mozilla/OSFileConstants.h"
@ -269,7 +269,7 @@ using namespace mozilla;
using namespace mozilla::dom;
using mozilla::dom::alarm::AlarmHalService;
using mozilla::dom::power::PowerManagerService;
using mozilla::dom::quota::QuotaManager;
using mozilla::dom::quota::QuotaManagerService;
using mozilla::dom::workers::ServiceWorkerManager;
using mozilla::dom::workers::WorkerDebuggerManager;
using mozilla::dom::UDPSocketChild;
@ -314,8 +314,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(DOMSessionStorageManager)
NS_GENERIC_FACTORY_CONSTRUCTOR(DOMLocalStorageManager)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(DOMRequestService,
DOMRequestService::FactoryCreate)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(QuotaManager,
QuotaManager::FactoryCreate)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(QuotaManagerService,
QuotaManagerService::FactoryCreate)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ServiceWorkerManager,
ServiceWorkerManager::GetInstance)
NS_GENERIC_FACTORY_CONSTRUCTOR(WorkerDebuggerManager)
@ -765,7 +765,7 @@ NS_DEFINE_NAMED_CID(NS_DOMLOCALSTORAGEMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_DOMJSON_CID);
NS_DEFINE_NAMED_CID(NS_TEXTEDITOR_CID);
NS_DEFINE_NAMED_CID(DOMREQUEST_SERVICE_CID);
NS_DEFINE_NAMED_CID(QUOTA_MANAGER_CID);
NS_DEFINE_NAMED_CID(QUOTAMANAGER_SERVICE_CID);
NS_DEFINE_NAMED_CID(SERVICEWORKERMANAGER_CID);
NS_DEFINE_NAMED_CID(WORKERDEBUGGERMANAGER_CID);
#ifdef MOZ_WIDGET_GONK
@ -1074,7 +1074,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNS_DOMJSON_CID, false, nullptr, NS_NewJSON },
{ &kNS_TEXTEDITOR_CID, false, nullptr, nsPlaintextEditorConstructor },
{ &kDOMREQUEST_SERVICE_CID, false, nullptr, DOMRequestServiceConstructor },
{ &kQUOTA_MANAGER_CID, false, nullptr, QuotaManagerConstructor },
{ &kQUOTAMANAGER_SERVICE_CID, false, nullptr, QuotaManagerServiceConstructor },
{ &kSERVICEWORKERMANAGER_CID, false, nullptr, ServiceWorkerManagerConstructor },
{ &kWORKERDEBUGGERMANAGER_CID, true, nullptr, WorkerDebuggerManagerConstructor },
#ifdef MOZ_WIDGET_GONK
@ -1243,7 +1243,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ "@mozilla.org/dom/json;1", &kNS_DOMJSON_CID },
{ "@mozilla.org/editor/texteditor;1", &kNS_TEXTEDITOR_CID },
{ DOMREQUEST_SERVICE_CONTRACTID, &kDOMREQUEST_SERVICE_CID },
{ QUOTA_MANAGER_CONTRACTID, &kQUOTA_MANAGER_CID },
{ QUOTAMANAGER_SERVICE_CONTRACTID, &kQUOTAMANAGER_SERVICE_CID },
{ SERVICEWORKERMANAGER_CONTRACTID, &kSERVICEWORKERMANAGER_CID },
{ WORKERDEBUGGERMANAGER_CONTRACTID, &kWORKERDEBUGGERMANAGER_CID },
#ifdef MOZ_WIDGET_GONK
@ -1346,8 +1346,8 @@ static const mozilla::Module::CategoryEntry kLayoutCategories[] = {
{ "net-channel-event-sinks", "CSPService", CSPSERVICE_CONTRACTID },
{ "net-channel-event-sinks", NS_MIXEDCONTENTBLOCKER_CONTRACTID, NS_MIXEDCONTENTBLOCKER_CONTRACTID },
{ "app-startup", "Script Security Manager", "service," NS_SCRIPTSECURITYMANAGER_CONTRACTID },
{ TOPIC_WEB_APP_CLEAR_DATA, "QuotaManager", "service," QUOTA_MANAGER_CONTRACTID },
{ OBSERVER_TOPIC_IDLE_DAILY, "QuotaManager", QUOTA_MANAGER_CONTRACTID },
{ TOPIC_WEB_APP_CLEAR_DATA, "QuotaManagerService", "service," QUOTAMANAGER_SERVICE_CONTRACTID },
{ OBSERVER_TOPIC_IDLE_DAILY, "QuotaManagerService", QUOTAMANAGER_SERVICE_CONTRACTID },
#ifdef MOZ_WIDGET_GONK
{ "app-startup", "Volume Service", "service," NS_VOLUMESERVICE_CONTRACTID },
#endif

View File

@ -491,44 +491,6 @@ SpecialPowersObserverAPI.prototype = {
return undefined; // See comment at the beginning of this function.
}
case 'SPQuotaManager': {
let qm = Cc['@mozilla.org/dom/quota/manager;1']
.getService(Ci.nsIQuotaManager);
let mm = aMessage.target
.QueryInterface(Ci.nsIFrameLoaderOwner)
.frameLoader
.messageManager;
let msg = aMessage.data;
let principal = msg.principal;
let op = msg.op;
if (op != 'clear' && op != 'getUsage' && op != 'reset') {
throw new SpecialPowersError('Invalid operation for SPQuotaManager');
}
if (op == 'clear') {
qm.clearStoragesForPrincipal(principal);
} else if (op == 'reset') {
qm.reset();
}
// We always use the getUsageForPrincipal callback even if we're clearing
// since we know that clear and getUsageForPrincipal are synchronized by the
// QuotaManager.
let callback = function(principal, usage, fileUsage) {
let reply = { id: msg.id };
if (op == 'getUsage') {
reply.usage = usage;
reply.fileUsage = fileUsage;
}
mm.sendAsyncMessage(aMessage.name, reply);
};
qm.getUsageForPrincipal(principal, callback);
return undefined; // See comment at the beginning of this function.
}
case "SPCleanUpSTSData": {
let origin = aMessage.data.origin;
let flags = aMessage.data.flags;

View File

@ -41,7 +41,6 @@ function SpecialPowers(window) {
"SpecialPowers.CreateFiles",
"SpecialPowers.RemoveFiles",
"SPPingService",
"SPQuotaManager",
"SPLoadExtension",
"SPStartupExtension",
"SPUnloadExtension",

View File

@ -47,7 +47,6 @@ function SpecialPowersAPI() {
this._observingPermissions = false;
this._fm = null;
this._cb = null;
this._quotaManagerCallbackInfos = null;
}
function bindDOMWindowUtils(aWindow) {
@ -1932,61 +1931,6 @@ SpecialPowersAPI.prototype = {
this._sendSyncMessage('SPObserverService', msg);
},
clearStorageForDoc: function(wrappedDocument, callback) {
this._quotaManagerRequest('clear', wrappedDocument, callback);
},
getStorageUsageForDoc: function(wrappedDocument, callback) {
this._quotaManagerRequest('getUsage', wrappedDocument, callback);
},
resetStorageForDoc: function(wrappedDocument, callback) {
this._quotaManagerRequest('reset', wrappedDocument, callback);
},
_quotaManagerRequest: function(op, wrappedDocument, callback) {
const messageTopic = "SPQuotaManager";
const id = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator)
.generateUUID()
.toString();
let callbackInfo = { id: id, callback: callback };
if (this._quotaManagerCallbackInfos) {
callbackInfo.listener = this._quotaManagerCallbackInfos[0].listener;
this._quotaManagerCallbackInfos.push(callbackInfo)
} else {
callbackInfo.listener = function(msg) {
msg = msg.data;
for (let index in this._quotaManagerCallbackInfos) {
let callbackInfo = this._quotaManagerCallbackInfos[index];
if (callbackInfo.id == msg.id) {
if (this._quotaManagerCallbackInfos.length > 1) {
this._quotaManagerCallbackInfos.splice(index, 1);
} else {
this._quotaManagerCallbackInfos = null;
this._removeMessageListener(messageTopic, callbackInfo.listener);
}
if ('usage' in msg) {
callbackInfo.callback(msg.usage, msg.fileUsage);
} else {
callbackInfo.callback();
}
}
}
}.bind(this);
this._addMessageListener(messageTopic, callbackInfo.listener);
this._quotaManagerCallbackInfos = [ callbackInfo ];
}
let principal = unwrapIfWrapped(wrappedDocument).nodePrincipal;
let msg = { op: op, principal: principal, id: id };
this._sendAsyncMessage(messageTopic, msg);
},
createDOMFile: function(path, options) {
return new File(path, options);
},

View File

@ -150,8 +150,8 @@ this.ForgetAboutSite = {
}
// Offline Storages
let qm = Cc["@mozilla.org/dom/quota/manager;1"].
getService(Ci.nsIQuotaManager);
let qms = Cc["@mozilla.org/dom/quota-manager-service;1"].
getService(Ci.nsIQuotaManagerService);
// delete data from both HTTP and HTTPS sites
let caUtils = {};
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
@ -162,8 +162,8 @@ this.ForgetAboutSite = {
let httpsURI = caUtils.makeURI("https://" + aDomain);
let httpPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(httpURI, {});
let httpsPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(httpsURI, {});
qm.clearStoragesForPrincipal(httpPrincipal);
qm.clearStoragesForPrincipal(httpsPrincipal);
qms.clearStoragesForPrincipal(httpPrincipal);
qms.clearStoragesForPrincipal(httpsPrincipal);
function onContentPrefsRemovalFinished() {
// Everybody else (including extensions)

View File

@ -102,6 +102,7 @@ var initTable = [
["blocklist", "@mozilla.org/extensions/blocklist;1", "nsIBlocklistService"],
["netUtils", "@mozilla.org/network/util;1", "nsINetUtil"],
["loadContextInfo", "@mozilla.org/load-context-info-factory;1", "nsILoadContextInfoFactory"],
["qms", "@mozilla.org/dom/quota-manager-service;1", "nsIQuotaManagerService"],
];
initTable.forEach(([name, contract, intf, enabled = true]) => {