Bug 1281103 - Support getting the group usage and the limit in QuotaManagerService. r=janv.

--HG--
extra : rebase_source : 609795f25eeab0d96f962799629e4e81492fb087
This commit is contained in:
Tom Tung 2016-06-24 10:24:06 +08:00
parent d634a99cad
commit 3b07e666f0
11 changed files with 131 additions and 10 deletions

View File

@ -145,7 +145,9 @@ QuotaUsageRequestChild::HandleResponse(const UsageResponse& aResponse)
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
mRequest->SetResult(aResponse.usage(), aResponse.fileUsage());
mRequest->SetResult(aResponse.usage(),
aResponse.fileUsage(),
aResponse.limit());
}
void

View File

@ -1008,11 +1008,16 @@ class GetUsageOp final
: public NormalOriginOperationBase
, public PQuotaUsageRequestParent
{
// If mGetGroupUsage is false, we use mUsageInfo to record the origin usage
// and the file usage. Otherwise, we use it to record the group usage and the
// limit.
UsageInfo mUsageInfo;
const UsageParams mParams;
nsCString mSuffix;
nsCString mGroup;
bool mIsApp;
bool mGetGroupUsage;
public:
explicit GetUsageOp(const UsageRequestParams& aParams);
@ -4583,6 +4588,40 @@ QuotaManager::GetGroupLimit() const
std::max<uint64_t>(x, 10 MB));
}
void
QuotaManager::GetGroupUsageAndLimit(const nsACString& aGroup,
UsageInfo* aUsageInfo)
{
AssertIsOnIOThread();
MOZ_ASSERT(aUsageInfo);
{
MutexAutoLock lock(mQuotaMutex);
aUsageInfo->SetLimit(GetGroupLimit());
aUsageInfo->ResetUsage();
GroupInfoPair* pair;
if (!mGroupInfoPairs.Get(aGroup, &pair)) {
return;
}
// Calculate temporary group usage
RefPtr<GroupInfo> temporaryGroupInfo =
pair->LockedGetGroupInfo(PERSISTENCE_TYPE_TEMPORARY);
if (temporaryGroupInfo) {
aUsageInfo->AppendToDatabaseUsage(temporaryGroupInfo->mUsage);
}
// Calculate default group usage
RefPtr<GroupInfo> defaultGroupInfo =
pair->LockedGetGroupInfo(PERSISTENCE_TYPE_DEFAULT);
if (defaultGroupInfo) {
aUsageInfo->AppendToDatabaseUsage(defaultGroupInfo->mUsage);
}
}
}
// static
void
QuotaManager::GetStorageId(PersistenceType aPersistenceType,
@ -5845,6 +5884,7 @@ GetUsageOp::GetUsageOp(const UsageRequestParams& aParams)
OriginScope::FromNull(),
/* aExclusive */ false)
, mParams(aParams.get_UsageParams())
, mGetGroupUsage(aParams.get_UsageParams().getGroupUsage())
{
AssertIsOnOwningThread();
MOZ_ASSERT(aParams.type() == UsageRequestParams::TUsageParams);
@ -5880,7 +5920,7 @@ GetUsageOp::DoInitOnMainThread()
// Figure out which origin we're dealing with.
nsCString origin;
rv = QuotaManager::GetInfoFromPrincipal(principal, nullptr, &mGroup, &origin,
rv = QuotaManager::GetInfoFromPrincipal(principal, &mSuffix, &mGroup, &origin,
&mIsApp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -5995,12 +6035,34 @@ nsresult
GetUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
{
AssertIsOnIOThread();
MOZ_ASSERT(mUsageInfo.TotalUsage() == 0);
PROFILER_LABEL("Quota", "GetUsageOp::DoDirectoryWork",
js::ProfileEntry::Category::OTHER);
// Add all the persistent/temporary/default storage files we care about.
nsresult rv;
if (mGetGroupUsage) {
nsCOMPtr<nsIFile> directory;
// Ensure origin is initialized first. It will initialize all origins for
// temporary storage including origins belonging to our group.
rv = aQuotaManager->EnsureOriginIsInitialized(PERSISTENCE_TYPE_TEMPORARY,
mSuffix, mGroup,
mOriginScope.GetOrigin(),
mIsApp,
getter_AddRefs(directory));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// Get cached usage and limit (the method doesn't have to stat any files).
aQuotaManager->GetGroupUsageAndLimit(mGroup, &mUsageInfo);
return NS_OK;
}
// Add all the persistent/temporary/default storage files we care about.
for (const PersistenceType type : kAllPersistenceTypes) {
rv = AddToUsage(aQuotaManager, type);
if (NS_WARN_IF(NS_FAILED(rv))) {
@ -6029,8 +6091,17 @@ GetUsageOp::SendResults()
if (NS_SUCCEEDED(mResultCode)) {
UsageResponse usageResponse;
// We'll get the group usage when mGetGroupUsage is true and get the
// origin usage when mGetGroupUsage is false.
usageResponse.usage() = mUsageInfo.TotalUsage();
usageResponse.fileUsage() = mUsageInfo.FileUsage();
if (mGetGroupUsage) {
usageResponse.limit() = mUsageInfo.Limit();
} else {
usageResponse.fileUsage() = mUsageInfo.FileUsage();
}
response = usageResponse;
} else {
response = mResultCode;

View File

@ -20,6 +20,7 @@ namespace quota {
struct UsageParams
{
PrincipalInfo principalInfo;
bool getGroupUsage;
};
union UsageRequestParams

View File

@ -12,6 +12,7 @@ struct UsageResponse
{
uint64_t usage;
uint64_t fileUsage;
uint64_t limit;
};
union UsageRequestResponse

View File

@ -347,6 +347,10 @@ public:
uint64_t
GetGroupLimit() const;
void
GetGroupUsageAndLimit(const nsACString& aGroup,
UsageInfo* aUsageInfo);
static void
GetStorageId(PersistenceType aPersistenceType,
const nsACString& aOrigin,

View File

@ -497,6 +497,7 @@ NS_IMPL_QUERY_INTERFACE(QuotaManagerService,
NS_IMETHODIMP
QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
nsIQuotaUsageCallback* aCallback,
bool aGetGroupUsage,
nsIQuotaUsageRequest** _retval)
{
MOZ_ASSERT(NS_IsMainThread());
@ -509,7 +510,6 @@ QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
UsageParams params;
PrincipalInfo& principalInfo = params.principalInfo();
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -520,6 +520,8 @@ QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
return NS_ERROR_UNEXPECTED;
}
params.getGroupUsage() = aGetGroupUsage;
nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
rv = InitiateRequest(info);

View File

@ -92,11 +92,12 @@ RequestBase::GetResultCode(nsresult* aResultCode)
}
UsageRequest::UsageRequest(nsIPrincipal* aPrincipal,
nsIQuotaUsageCallback* aCallback)
nsIQuotaUsageCallback* aCallback)
: RequestBase(aPrincipal)
, mCallback(aCallback)
, mUsage(0)
, mFileUsage(0)
, mLimit(0)
, mBackgroundActor(nullptr)
, mCanceled(false)
{
@ -125,13 +126,14 @@ UsageRequest::SetBackgroundActor(QuotaUsageRequestChild* aBackgroundActor)
}
void
UsageRequest::SetResult(uint64_t aUsage, uint64_t aFileUsage)
UsageRequest::SetResult(uint64_t aUsage, uint64_t aFileUsage, uint64_t aLimit)
{
AssertIsOnOwningThread();
MOZ_ASSERT(!mHaveResultOrErrorCode);
mUsage = aUsage;
mFileUsage = aFileUsage;
mLimit = aLimit;
mHaveResultOrErrorCode = true;
FireCallback();
@ -173,6 +175,20 @@ UsageRequest::GetFileUsage(uint64_t* aFileUsage)
return NS_OK;
}
NS_IMETHODIMP
UsageRequest::GetLimit(uint64_t* aLimit)
{
AssertIsOnOwningThread();
MOZ_ASSERT(aLimit);
if (!mHaveResultOrErrorCode) {
return NS_ERROR_FAILURE;
}
*aLimit = mLimit;
return NS_OK;
}
NS_IMETHODIMP
UsageRequest::GetCallback(nsIQuotaUsageCallback** aCallback)
{

View File

@ -74,6 +74,9 @@ class UsageRequest final
uint64_t mUsage;
uint64_t mFileUsage;
// Group Limit.
uint64_t mLimit;
QuotaUsageRequestChild* mBackgroundActor;
bool mCanceled;
@ -94,7 +97,7 @@ public:
}
void
SetResult(uint64_t aUsage, uint64_t aFileUsage);
SetResult(uint64_t aUsage, uint64_t aFileUsage, uint64_t aLimit);
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_NSIQUOTAREQUESTBASE(RequestBase::)

View File

@ -18,7 +18,7 @@ class UsageInfo
{
public:
UsageInfo()
: mCanceled(false), mDatabaseUsage(0), mFileUsage(0)
: mCanceled(false), mDatabaseUsage(0), mFileUsage(0), mLimit(0)
{ }
virtual ~UsageInfo()
@ -52,6 +52,12 @@ public:
IncrementUsage(&mFileUsage, aUsage);
}
void
SetLimit(uint64_t aLimit)
{
mLimit = aLimit;
}
uint64_t
DatabaseUsage()
{
@ -64,6 +70,12 @@ public:
return mFileUsage;
}
uint64_t
Limit()
{
return mLimit;
}
uint64_t
TotalUsage()
{
@ -98,6 +110,7 @@ protected:
private:
uint64_t mDatabaseUsage;
uint64_t mFileUsage;
uint64_t mLimit;
};
END_QUOTA_NAMESPACE

View File

@ -22,10 +22,16 @@ interface nsIQuotaManagerService : nsISupports
* A principal for the origin whose usage is being queried.
* @param aCallback
* The callback that will be called when the usage is available.
* @param aGetGroupUsage
* An optional flag to indicate whether getting group usage and limit
* or origin usage and file usage. The default value is false.
* Note: Origin usage here represents total usage of an origin. However,
* group usage here represents only non-persistent usage of a group.
*/
nsIQuotaUsageRequest
getUsageForPrincipal(in nsIPrincipal aPrincipal,
in nsIQuotaUsageCallback aCallback);
in nsIQuotaUsageCallback aCallback,
[optional] in boolean aGetGroupUsage);
/**
* Removes all storages. The files may not be deleted immediately depending

View File

@ -25,6 +25,8 @@ interface nsIQuotaUsageRequest : nsIQuotaRequestBase
readonly attribute unsigned long long fileUsage;
readonly attribute unsigned long long limit;
attribute nsIQuotaUsageCallback callback;
void