Bug 1722668 - Implement nsIQuotaManagerService::getFullOriginMetadata; r=dom-storage-reviewers,jari

Differential Revision: https://phabricator.services.mozilla.com/D125168
This commit is contained in:
Jan Varga 2021-09-22 19:08:33 +00:00
Родитель a1b9c83581
Коммит a294b48418
13 изменённых файлов: 316 добавлений и 0 удалений

Просмотреть файл

@ -313,6 +313,27 @@ void QuotaRequestChild::HandleResponse(const nsTArray<nsCString>& aResponse) {
mRequest->SetResult(variant);
}
void QuotaRequestChild::HandleResponse(
const GetFullOriginMetadataResponse& aResponse) {
AssertIsOnOwningThread();
MOZ_ASSERT(mRequest);
RefPtr<nsVariant> variant = new nsVariant();
if (aResponse.maybeFullOriginMetadata()) {
RefPtr<FullOriginMetadataResult> result =
new FullOriginMetadataResult(*aResponse.maybeFullOriginMetadata());
variant->SetAsInterface(NS_GET_IID(nsIQuotaFullOriginMetadataResult),
result);
} else {
variant->SetAsVoid();
}
mRequest->SetResult(variant);
}
void QuotaRequestChild::ActorDestroy(ActorDestroyReason aWhy) {
AssertIsOnOwningThread();
}
@ -361,6 +382,10 @@ mozilla::ipc::IPCResult QuotaRequestChild::Recv__delete__(
aResponse.get_InitializeTemporaryOriginResponse().created());
break;
case RequestResponse::TGetFullOriginMetadataResponse:
HandleResponse(aResponse.get_GetFullOriginMetadataResponse());
break;
case RequestResponse::TPersistedResponse:
HandleResponse(aResponse.get_PersistedResponse().persisted());
break;

Просмотреть файл

@ -144,6 +144,8 @@ class QuotaRequestChild final : public PQuotaRequestChild {
void HandleResponse(const nsTArray<nsCString>& aResponse);
void HandleResponse(const GetFullOriginMetadataResponse& aResponse);
// IPDL methods are only called by IPDL.
virtual void ActorDestroy(ActorDestroyReason aWhy) override;

Просмотреть файл

@ -827,6 +827,8 @@ class OriginInfo final {
OriginMetadata FlattenToOriginMetadata() const;
FullOriginMetadata LockedFlattenToFullOriginMetadata() const;
nsresult LockedBindToStatement(mozIStorageStatement* aStatement) const;
private:
@ -1528,6 +1530,21 @@ class InitializeTemporaryOriginOp final : public InitializeOriginRequestBase {
void GetResponse(RequestResponse& aResponse) override;
};
class GetFullOriginMetadataOp : public QuotaRequestBase {
const OriginMetadata mOriginMetadata;
Maybe<FullOriginMetadata> mMaybeFullOriginMetadata;
public:
explicit GetFullOriginMetadataOp(const GetFullOriginMetadataParams& aParams);
void Init(Quota& aQuota) override;
private:
nsresult DoDirectoryWork(QuotaManager& aQuotaManager) override;
void GetResponse(RequestResponse& aResponse) override;
};
class ResetOrClearOp final : public QuotaRequestBase {
const bool mClear;
@ -6512,6 +6529,23 @@ uint64_t QuotaManager::GetOriginUsage(
return usage;
}
Maybe<FullOriginMetadata> QuotaManager::GetFullOriginMetadata(
const OriginMetadata& aOriginMetadata) {
AssertIsOnIOThread();
MOZ_DIAGNOSTIC_ASSERT(mStorageConnection);
MOZ_DIAGNOSTIC_ASSERT(mTemporaryStorageInitialized);
MutexAutoLock lock(mQuotaMutex);
RefPtr<OriginInfo> originInfo =
LockedGetOriginInfo(aOriginMetadata.mPersistenceType, aOriginMetadata);
if (originInfo) {
return Some(originInfo->LockedFlattenToFullOriginMetadata());
}
return Nothing();
}
void QuotaManager::NotifyStoragePressure(uint64_t aUsage) {
mQuotaMutex.AssertNotCurrentThreadOwns();
@ -7340,6 +7374,12 @@ OriginMetadata OriginInfo::FlattenToOriginMetadata() const {
mGroupInfo->mPersistenceType};
}
FullOriginMetadata OriginInfo::LockedFlattenToFullOriginMetadata() const {
AssertCurrentThreadOwnsQuotaMutex();
return {FlattenToOriginMetadata(), mPersisted, mAccessTime};
}
nsresult OriginInfo::LockedBindToStatement(
mozIStorageStatement* aStatement) const {
AssertCurrentThreadOwnsQuotaMutex();
@ -8018,6 +8058,23 @@ bool Quota::VerifyRequestParams(const RequestParams& aParams) const {
break;
}
case RequestParams::TGetFullOriginMetadataParams: {
const GetFullOriginMetadataParams& params =
aParams.get_GetFullOriginMetadataParams();
if (NS_WARN_IF(!IsBestEffortPersistenceType(params.persistenceType()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (NS_WARN_IF(
!QuotaManager::IsPrincipalInfoValid(params.principalInfo()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
}
case RequestParams::TClearOriginParams: {
const ClearResetOriginParams& params =
aParams.get_ClearOriginParams().commonParams();
@ -8248,6 +8305,10 @@ PQuotaRequestParent* Quota::AllocPQuotaRequestParent(
case RequestParams::TInitializeTemporaryOriginParams:
return MakeRefPtr<InitializeTemporaryOriginOp>(aParams);
case RequestParams::TGetFullOriginMetadataParams:
return MakeRefPtr<GetFullOriginMetadataOp>(
aParams.get_GetFullOriginMetadataParams());
case RequestParams::TClearOriginParams:
return MakeRefPtr<ClearOriginOp>(aParams);
@ -9059,6 +9120,49 @@ void InitializeTemporaryOriginOp::GetResponse(RequestResponse& aResponse) {
aResponse = InitializeTemporaryOriginResponse(mCreated);
}
GetFullOriginMetadataOp::GetFullOriginMetadataOp(
const GetFullOriginMetadataParams& aParams)
: QuotaRequestBase(/* aExclusive */ false),
mOriginMetadata(QuotaManager::GetInfoFromValidatedPrincipalInfo(
aParams.principalInfo()),
aParams.persistenceType()) {
AssertIsOnOwningThread();
}
void GetFullOriginMetadataOp::Init(Quota& aQuota) {
AssertIsOnOwningThread();
QuotaRequestBase::Init(aQuota);
mNeedsDirectoryLocking = false;
}
nsresult GetFullOriginMetadataOp::DoDirectoryWork(QuotaManager& aQuotaManager) {
AssertIsOnIOThread();
AUTO_PROFILER_LABEL("GetFullOriginMetadataOp::DoDirectoryWork", OTHER);
// Ensure temporary storage is initialized. If temporary storage hasn't
// been initialized yet, the method will initialize it by traversing the
// repositories for temporary and default storage (including our origin).
QM_TRY(aQuotaManager.EnsureTemporaryStorageIsInitialized());
// Get metadata cached in memory (the method doesn't have to stat any
// files).
mMaybeFullOriginMetadata =
aQuotaManager.GetFullOriginMetadata(mOriginMetadata);
return NS_OK;
}
void GetFullOriginMetadataOp::GetResponse(RequestResponse& aResponse) {
AssertIsOnOwningThread();
aResponse = GetFullOriginMetadataResponse();
aResponse.get_GetFullOriginMetadataResponse().maybeFullOriginMetadata() =
std::move(mMaybeFullOriginMetadata);
}
ResetOrClearOp::ResetOrClearOp(bool aClear)
: QuotaRequestBase(/* aExclusive */ true), mClear(aClear) {
AssertIsOnOwningThread();

Просмотреть файл

@ -57,6 +57,12 @@ struct InitializeTemporaryOriginParams
PrincipalInfo principalInfo;
};
struct GetFullOriginMetadataParams
{
PersistenceType persistenceType;
PrincipalInfo principalInfo;
};
struct AllUsageParams
{
bool getAll;
@ -135,6 +141,7 @@ union RequestParams
InitTemporaryStorageParams;
InitializePersistentOriginParams;
InitializeTemporaryOriginParams;
GetFullOriginMetadataParams;
ClearOriginParams;
ResetOriginParams;
ClearDataParams;

Просмотреть файл

@ -4,6 +4,9 @@
include protocol PQuota;
using mozilla::dom::quota::FullOriginMetadata
from "mozilla/dom/quota/CommonMetadata.h";
namespace mozilla {
namespace dom {
namespace quota {
@ -41,6 +44,11 @@ struct InitializeTemporaryOriginResponse
bool created;
};
struct GetFullOriginMetadataResponse
{
FullOriginMetadata? maybeFullOriginMetadata;
};
struct ClearOriginResponse
{
};
@ -91,6 +99,7 @@ union RequestResponse
InitTemporaryStorageResponse;
InitializePersistentOriginResponse;
InitializeTemporaryOriginResponse;
GetFullOriginMetadataResponse;
ClearOriginResponse;
ResetOriginResponse;
ClearDataResponse;

Просмотреть файл

@ -366,6 +366,9 @@ class QuotaManager final : public BackgroundThreadObject {
uint64_t GetOriginUsage(const PrincipalMetadata& aPrincipalMetadata);
Maybe<FullOriginMetadata> GetFullOriginMetadata(
const OriginMetadata& aOriginMetadata);
void NotifyStoragePressure(uint64_t aUsage);
// Record a quota client shutdown step, if shutting down.

Просмотреть файл

@ -602,6 +602,41 @@ QuotaManagerService::InitializeTemporaryOrigin(
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::GetFullOriginMetadata(const nsACString& aPersistenceType,
nsIPrincipal* aPrincipal,
nsIQuotaRequest** _retval) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
QM_TRY(OkIf(StaticPrefs::dom_quotaManager_testing()), NS_ERROR_UNEXPECTED);
const auto maybePersistenceType =
PersistenceTypeFromString(aPersistenceType, fallible);
QM_TRY(OkIf(maybePersistenceType.isSome()), NS_ERROR_INVALID_ARG);
QM_TRY(OkIf(IsBestEffortPersistenceType(*maybePersistenceType)),
NS_ERROR_INVALID_ARG);
PrincipalInfo principalInfo;
QM_TRY(PrincipalToPrincipalInfo(aPrincipal, &principalInfo));
QM_TRY(OkIf(QuotaManager::IsPrincipalInfoValid(principalInfo)),
NS_ERROR_INVALID_ARG);
RefPtr<Request> request = new Request();
GetFullOriginMetadataParams params;
params.persistenceType() = *maybePersistenceType;
params.principalInfo() = std::move(principalInfo);
RequestInfo info(request, params);
QM_TRY(InitiateRequest(info));
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::GetUsage(nsIQuotaUsageCallback* aCallback, bool aGetAll,
nsIQuotaUsageRequest** _retval) {

Просмотреть файл

@ -13,6 +13,53 @@
namespace mozilla::dom::quota {
FullOriginMetadataResult::FullOriginMetadataResult(
const FullOriginMetadata& aFullOriginMetadata)
: mFullOriginMetadata(aFullOriginMetadata) {}
NS_IMPL_ISUPPORTS(FullOriginMetadataResult, nsIQuotaFullOriginMetadataResult)
NS_IMETHODIMP
FullOriginMetadataResult::GetSuffix(nsACString& aSuffix) {
aSuffix = mFullOriginMetadata.mSuffix;
return NS_OK;
}
NS_IMETHODIMP
FullOriginMetadataResult::GetGroup(nsACString& aGroup) {
aGroup = mFullOriginMetadata.mGroup;
return NS_OK;
}
NS_IMETHODIMP
FullOriginMetadataResult::GetOrigin(nsACString& aOrigin) {
aOrigin = mFullOriginMetadata.mOrigin;
return NS_OK;
}
NS_IMETHODIMP
FullOriginMetadataResult::GetPersistenceType(nsACString& aPersistenceType) {
aPersistenceType =
PersistenceTypeToString(mFullOriginMetadata.mPersistenceType);
return NS_OK;
}
NS_IMETHODIMP
FullOriginMetadataResult::GetPersisted(bool* aPersisted) {
MOZ_ASSERT(aPersisted);
*aPersisted = mFullOriginMetadata.mPersisted;
return NS_OK;
}
NS_IMETHODIMP
FullOriginMetadataResult::GetLastAccessTime(int64_t* aLastAccessTime) {
MOZ_ASSERT(aLastAccessTime);
*aLastAccessTime = mFullOriginMetadata.mLastAccessTime;
return NS_OK;
}
UsageResult::UsageResult(const nsACString& aOrigin, bool aPersisted,
uint64_t aUsage, uint64_t aLastAccessed)
: mOrigin(aOrigin),

Просмотреть файл

@ -8,6 +8,7 @@
#define mozilla_dom_quota_QuotaResults_h
#include <cstdint>
#include "mozilla/dom/quota/CommonMetadata.h"
#include "nsIQuotaResults.h"
#include "nsISupports.h"
#include "nsString.h"
@ -16,6 +17,20 @@ namespace mozilla {
namespace dom {
namespace quota {
class FullOriginMetadataResult : public nsIQuotaFullOriginMetadataResult {
const FullOriginMetadata mFullOriginMetadata;
public:
explicit FullOriginMetadataResult(
const FullOriginMetadata& aFullOriginMetadata);
private:
virtual ~FullOriginMetadataResult() = default;
NS_DECL_ISUPPORTS
NS_DECL_NSIQUOTAFULLORIGINMETADATARESULT
};
class UsageResult : public nsIQuotaUsageResult {
nsCString mOrigin;
uint64_t mUsage;

Просмотреть файл

@ -11,6 +11,7 @@
#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/quota/Client.h"
#include "mozilla/dom/quota/CommonMetadata.h"
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/OriginAttributes.h"
@ -29,6 +30,30 @@ struct ParamTraits<mozilla::dom::quota::Client::Type>
mozilla::dom::quota::Client::IDB,
mozilla::dom::quota::Client::TYPE_MAX> {};
template <>
struct ParamTraits<mozilla::dom::quota::FullOriginMetadata> {
using ParamType = mozilla::dom::quota::FullOriginMetadata;
static void Write(Message* aMsg, const ParamType& aParam) {
WriteParam(aMsg, aParam.mSuffix);
WriteParam(aMsg, aParam.mGroup);
WriteParam(aMsg, aParam.mOrigin);
WriteParam(aMsg, aParam.mPersistenceType);
WriteParam(aMsg, aParam.mPersisted);
WriteParam(aMsg, aParam.mLastAccessTime);
}
static bool Read(const Message* aMsg, PickleIterator* aIter,
ParamType* aResult) {
return ReadParam(aMsg, aIter, &aResult->mSuffix) &&
ReadParam(aMsg, aIter, &aResult->mGroup) &&
ReadParam(aMsg, aIter, &aResult->mOrigin) &&
ReadParam(aMsg, aIter, &aResult->mPersistenceType) &&
ReadParam(aMsg, aIter, &aResult->mPersisted) &&
ReadParam(aMsg, aIter, &aResult->mLastAccessTime);
}
};
template <>
struct ParamTraits<mozilla::OriginAttributesPattern> {
typedef mozilla::OriginAttributesPattern paramType;

Просмотреть файл

@ -93,6 +93,24 @@ interface nsIQuotaManagerService : nsISupports
initializeTemporaryOrigin(in ACString aPersistenceType,
in nsIPrincipal aPrincipal);
/**
* Gets full origin metadata cached in memory for the given persistence type
* and origin.
*
* NOTE: This operation may still be delayed by other operations on the QM
* I/O thread that are peforming I/O.
*
* @param aPersistenceType
* A string that tells what persistence type will be used for getting
* the metadata (either "temporary" or "default").
* @param aPrincipal
* A principal that tells which origin will be used for getting the
* metadata.
*/
[must_use] nsIQuotaRequest
getFullOriginMetadata(in ACString aPersistenceType,
in nsIPrincipal aPrincipal);
/**
* Schedules an asynchronous callback that will inspect all origins and
* return the total amount of disk space being used by storages for each

Просмотреть файл

@ -6,6 +6,22 @@
#include "nsISupports.idl"
[scriptable, function, uuid(4d8def75-014e-404d-bf30-e2f0Bfcf4d89)]
interface nsIQuotaFullOriginMetadataResult : nsISupports
{
readonly attribute ACString suffix;
readonly attribute ACString group;
readonly attribute ACString origin;
readonly attribute ACString persistenceType;
readonly attribute boolean persisted;
readonly attribute long long lastAccessTime;
};
[scriptable, function, uuid(d8c9328b-9aa8-4f5d-90e6-482de4a6d5b8)]
interface nsIQuotaUsageResult : nsISupports
{

Просмотреть файл

@ -168,6 +168,16 @@ function initTemporaryOrigin(persistence, principal, callback) {
return request;
}
function getFullOriginMetadata(persistence, principal, callback) {
const request = SpecialPowers._getQuotaManager().getFullOriginMetadata(
persistence,
principal
);
request.callback = callback;
return request;
}
function clearClient(principal, persistence, client, callback) {
let request = SpecialPowers._getQuotaManager().clearStoragesForPrincipal(
principal,