mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1298329 - Part 1: Implement persist/persisted in QuotaManager and expose them to QuotaManagerService; r=janv
This commit is contained in:
parent
a207c2fcb5
commit
b21732dac3
@ -18796,10 +18796,12 @@ Maintenance::DirectoryWork()
|
||||
MOZ_ASSERT(origin.IsEmpty());
|
||||
|
||||
int64_t dummyTimeStamp;
|
||||
bool dummyPersisted;
|
||||
nsCString dummySuffix;
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
quotaManager->GetDirectoryMetadata2(originDir,
|
||||
&dummyTimeStamp,
|
||||
&dummyPersisted,
|
||||
dummySuffix,
|
||||
group,
|
||||
origin)))) {
|
||||
|
@ -272,6 +272,7 @@ QuotaRequestChild::Recv__delete__(const RequestResponse& aResponse)
|
||||
case RequestResponse::TClearDataResponse:
|
||||
case RequestResponse::TClearAllResponse:
|
||||
case RequestResponse::TResetAllResponse:
|
||||
case RequestResponse::TPersistResponse:
|
||||
HandleResponse();
|
||||
break;
|
||||
|
||||
@ -279,6 +280,10 @@ QuotaRequestChild::Recv__delete__(const RequestResponse& aResponse)
|
||||
HandleResponse(aResponse.get_InitOriginResponse().created());
|
||||
break;
|
||||
|
||||
case RequestResponse::TPersistedResponse:
|
||||
HandleResponse(aResponse.get_PersistedResponse().persisted());
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unknown response type!");
|
||||
}
|
||||
|
@ -1255,6 +1255,63 @@ private:
|
||||
GetResponse(RequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
class PersistRequestBase
|
||||
: public QuotaRequestBase
|
||||
{
|
||||
const PrincipalInfo mPrincipalInfo;
|
||||
|
||||
protected:
|
||||
nsCString mSuffix;
|
||||
nsCString mGroup;
|
||||
|
||||
public:
|
||||
bool
|
||||
Init(Quota* aQuota) override;
|
||||
|
||||
protected:
|
||||
explicit PersistRequestBase(const PrincipalInfo& aPrincipalInfo);
|
||||
|
||||
private:
|
||||
nsresult
|
||||
DoInitOnMainThread() override;
|
||||
};
|
||||
|
||||
class PersistedOp final
|
||||
: public PersistRequestBase
|
||||
{
|
||||
bool mPersisted;
|
||||
|
||||
public:
|
||||
explicit PersistedOp(const RequestParams& aParams);
|
||||
|
||||
private:
|
||||
~PersistedOp()
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
DoDirectoryWork(QuotaManager* aQuotaManager) override;
|
||||
|
||||
void
|
||||
GetResponse(RequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
class PersistOp final
|
||||
: public PersistRequestBase
|
||||
{
|
||||
public:
|
||||
explicit PersistOp(const RequestParams& aParams);
|
||||
|
||||
private:
|
||||
~PersistOp()
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
DoDirectoryWork(QuotaManager* aQuotaManager) override;
|
||||
|
||||
void
|
||||
GetResponse(RequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* Helper Functions
|
||||
******************************************************************************/
|
||||
@ -1852,6 +1909,52 @@ EnsureDirectory(nsIFile* aDirectory, bool* aCreated)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
EnsureOriginDirectory(nsIFile* aDirectory, bool* aCreated)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
nsresult rv;
|
||||
|
||||
#ifndef RELEASE_OR_BETA
|
||||
bool exists;
|
||||
rv = aDirectory->Exists(&exists);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
nsString leafName;
|
||||
nsresult rv = aDirectory->GetLeafName(leafName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!leafName.EqualsLiteral(kChromeOrigin)) {
|
||||
nsCString spec;
|
||||
OriginAttributes attrs;
|
||||
OriginParser::ResultType result =
|
||||
OriginParser::ParseOrigin(NS_ConvertUTF16toUTF8(leafName),
|
||||
spec,
|
||||
&attrs);
|
||||
if (NS_WARN_IF(result != OriginParser::ValidOrigin)) {
|
||||
QM_WARNING("Preventing creation of a new origin directory which is not "
|
||||
"supported by our origin parser or is obsolete!");
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = EnsureDirectory(aDirectory, aCreated);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
enum FileFlag {
|
||||
kTruncateFileFlag,
|
||||
kUpdateFileFlag,
|
||||
@ -2077,6 +2180,7 @@ CreateDirectoryMetadata(nsIFile* aDirectory, int64_t aTimestamp,
|
||||
nsresult
|
||||
CreateDirectoryMetadata2(nsIFile* aDirectory,
|
||||
int64_t aTimestamp,
|
||||
bool aPersisted,
|
||||
const nsACString& aSuffix,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
@ -2108,8 +2212,7 @@ CreateDirectoryMetadata2(nsIFile* aDirectory,
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Reserved for navigator.persist()
|
||||
rv = stream->WriteBoolean(false);
|
||||
rv = stream->WriteBoolean(aPersisted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -2168,6 +2271,43 @@ CreateDirectoryMetadata2(nsIFile* aDirectory,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CreateDirectoryMetadataFiles(nsIFile* aDirectory,
|
||||
bool aPersisted,
|
||||
const nsACString& aSuffix,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
int64_t* aTimestamp)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
int64_t timestamp = PR_Now();
|
||||
|
||||
nsresult rv = CreateDirectoryMetadata(aDirectory,
|
||||
timestamp,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = CreateDirectoryMetadata2(aDirectory,
|
||||
timestamp,
|
||||
aPersisted,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aTimestamp) {
|
||||
*aTimestamp = timestamp;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetBinaryInputStream(nsIFile* aDirectory,
|
||||
const nsAString& aFilename,
|
||||
@ -3512,6 +3652,8 @@ QuotaManager::UpdateOriginAccessTime(PersistenceType aPersistenceType,
|
||||
void
|
||||
QuotaManager::RemoveQuota()
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
MutexAutoLock lock(mQuotaMutex);
|
||||
|
||||
for (auto iter = mGroupInfoPairs.Iter(); !iter.Done(); iter.Next()) {
|
||||
@ -3637,6 +3779,40 @@ QuotaManager::GetQuotaObject(PersistenceType aPersistenceType,
|
||||
return GetQuotaObject(aPersistenceType, aGroup, aOrigin, file);
|
||||
}
|
||||
|
||||
Nullable<bool>
|
||||
QuotaManager::OriginPersisted(const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
MutexAutoLock lock(mQuotaMutex);
|
||||
|
||||
RefPtr<OriginInfo> originInfo = LockedGetOriginInfo(PERSISTENCE_TYPE_DEFAULT,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
if (originInfo) {
|
||||
return Nullable<bool>(originInfo->LockedPersisted());
|
||||
}
|
||||
|
||||
return Nullable<bool>();
|
||||
}
|
||||
|
||||
void
|
||||
QuotaManager::PersistOrigin(const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
MutexAutoLock lock(mQuotaMutex);
|
||||
|
||||
RefPtr<OriginInfo> originInfo = LockedGetOriginInfo(PERSISTENCE_TYPE_DEFAULT,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
if (originInfo && !originInfo->LockedPersisted()) {
|
||||
originInfo->LockedPersist();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
QuotaManager::AbortOperationsForProcess(ContentParentId aContentParentId)
|
||||
{
|
||||
@ -3691,6 +3867,7 @@ QuotaManager::RestoreDirectoryMetadata2(nsIFile* aDirectory, bool aPersistent)
|
||||
nsresult
|
||||
QuotaManager::GetDirectoryMetadata2(nsIFile* aDirectory,
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted,
|
||||
nsACString& aSuffix,
|
||||
nsACString& aGroup,
|
||||
nsACString& aOrigin)
|
||||
@ -3698,6 +3875,7 @@ QuotaManager::GetDirectoryMetadata2(nsIFile* aDirectory,
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aDirectory);
|
||||
MOZ_ASSERT(aTimestamp);
|
||||
MOZ_ASSERT(aPersisted);
|
||||
MOZ_ASSERT(mStorageInitialized);
|
||||
|
||||
nsCOMPtr<nsIBinaryInputStream> binaryStream;
|
||||
@ -3750,6 +3928,7 @@ QuotaManager::GetDirectoryMetadata2(nsIFile* aDirectory,
|
||||
}
|
||||
|
||||
*aTimestamp = timestamp;
|
||||
*aPersisted = persisted;
|
||||
aSuffix = suffix;
|
||||
aGroup = group;
|
||||
aOrigin = origin;
|
||||
@ -3760,12 +3939,14 @@ nsresult
|
||||
QuotaManager::GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
|
||||
bool aPersistent,
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted,
|
||||
nsACString& aSuffix,
|
||||
nsACString& aGroup,
|
||||
nsACString& aOrigin)
|
||||
{
|
||||
nsresult rv = GetDirectoryMetadata2(aDirectory,
|
||||
aTimestamp,
|
||||
aPersisted,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
@ -3777,6 +3958,7 @@ QuotaManager::GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
|
||||
|
||||
rv = GetDirectoryMetadata2(aDirectory,
|
||||
aTimestamp,
|
||||
aPersisted,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
@ -3789,11 +3971,13 @@ QuotaManager::GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
|
||||
}
|
||||
|
||||
nsresult
|
||||
QuotaManager::GetDirectoryMetadata2(nsIFile* aDirectory, int64_t* aTimestamp)
|
||||
QuotaManager::GetDirectoryMetadata2(nsIFile* aDirectory,
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(aDirectory);
|
||||
MOZ_ASSERT(aTimestamp);
|
||||
MOZ_ASSERT(aTimestamp || aPersisted);
|
||||
MOZ_ASSERT(mStorageInitialized);
|
||||
|
||||
nsCOMPtr<nsIBinaryInputStream> binaryStream;
|
||||
@ -3810,23 +3994,37 @@ QuotaManager::GetDirectoryMetadata2(nsIFile* aDirectory, int64_t* aTimestamp)
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aTimestamp = timestamp;
|
||||
bool persisted;
|
||||
if (aPersisted) {
|
||||
rv = binaryStream->ReadBoolean(&persisted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (aTimestamp) {
|
||||
*aTimestamp = timestamp;
|
||||
}
|
||||
if (aPersisted) {
|
||||
*aPersisted = persisted;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
QuotaManager::GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
|
||||
bool aPersistent,
|
||||
int64_t* aTimestamp)
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted)
|
||||
{
|
||||
nsresult rv = GetDirectoryMetadata2(aDirectory, aTimestamp);
|
||||
nsresult rv = GetDirectoryMetadata2(aDirectory, aTimestamp, aPersisted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
rv = RestoreDirectoryMetadata2(aDirectory, aPersistent);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = GetDirectoryMetadata2(aDirectory, aTimestamp);
|
||||
rv = GetDirectoryMetadata2(aDirectory, aTimestamp, aPersisted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -3899,12 +4097,14 @@ QuotaManager::InitializeRepository(PersistenceType aPersistenceType)
|
||||
}
|
||||
|
||||
int64_t timestamp;
|
||||
bool persisted;
|
||||
nsCString suffix;
|
||||
nsCString group;
|
||||
nsCString origin;
|
||||
rv = GetDirectoryMetadata2WithRestore(childDirectory,
|
||||
/* aPersistent */ false,
|
||||
×tamp,
|
||||
&persisted,
|
||||
suffix,
|
||||
group,
|
||||
origin);
|
||||
@ -3912,8 +4112,8 @@ QuotaManager::InitializeRepository(PersistenceType aPersistenceType)
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = InitializeOrigin(aPersistenceType, group, origin, timestamp,
|
||||
/* aPersisted */ false, childDirectory);
|
||||
rv = InitializeOrigin(aPersistenceType, group, origin, timestamp, persisted,
|
||||
childDirectory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -4820,66 +5020,29 @@ QuotaManager::EnsureOriginIsInitializedInternal(
|
||||
CheckTemporaryStorageLimits();
|
||||
}
|
||||
|
||||
int64_t timestamp;
|
||||
|
||||
#ifndef RELEASE_OR_BETA
|
||||
bool exists;
|
||||
rv = directory->Exists(&exists);
|
||||
bool created;
|
||||
rv = EnsureOriginDirectory(directory, &created);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
nsString leafName;
|
||||
nsresult rv = directory->GetLeafName(leafName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!leafName.EqualsLiteral(kChromeOrigin)) {
|
||||
nsCString spec;
|
||||
OriginAttributes attrs;
|
||||
OriginParser::ResultType result =
|
||||
OriginParser::ParseOrigin(NS_ConvertUTF16toUTF8(leafName),
|
||||
spec,
|
||||
&attrs);
|
||||
if (NS_WARN_IF(result != OriginParser::ValidOrigin)) {
|
||||
QM_WARNING("Preventing creation of a new origin directory which is not "
|
||||
"supported by our origin parser or is obsolete!");
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool created;
|
||||
rv = EnsureDirectory(directory, &created);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
int64_t timestamp;
|
||||
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||
if (created) {
|
||||
timestamp = PR_Now();
|
||||
|
||||
rv = CreateDirectoryMetadata(directory,
|
||||
timestamp,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
rv = CreateDirectoryMetadataFiles(directory,
|
||||
/* aPersisted */ true,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin,
|
||||
×tamp);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = CreateDirectoryMetadata2(directory,
|
||||
timestamp,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
rv = GetDirectoryMetadata2WithRestore(directory,
|
||||
/* aPersistent */ true,
|
||||
×tamp);
|
||||
×tamp,
|
||||
/* aPersisted */ nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -4893,24 +5056,16 @@ QuotaManager::EnsureOriginIsInitializedInternal(
|
||||
|
||||
mInitializedOrigins.AppendElement(aOrigin);
|
||||
} else if (created) {
|
||||
timestamp = PR_Now();
|
||||
|
||||
rv = CreateDirectoryMetadata(directory,
|
||||
timestamp,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
rv = CreateDirectoryMetadataFiles(directory,
|
||||
/* aPersisted */ false,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin,
|
||||
×tamp);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = CreateDirectoryMetadata2(directory,
|
||||
timestamp,
|
||||
aSuffix,
|
||||
aGroup,
|
||||
aOrigin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = InitializeOrigin(aPersistenceType, aGroup, aOrigin, timestamp,
|
||||
/* aPersisted */ false, directory);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -5228,6 +5383,25 @@ QuotaManager::LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType,
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<OriginInfo>
|
||||
QuotaManager::LockedGetOriginInfo(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
mQuotaMutex.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(aPersistenceType != PERSISTENCE_TYPE_PERSISTENT);
|
||||
|
||||
GroupInfoPair* pair;
|
||||
if (mGroupInfoPairs.Get(aGroup, &pair)) {
|
||||
RefPtr<GroupInfo> groupInfo = pair->LockedGetGroupInfo(aPersistenceType);
|
||||
if (groupInfo) {
|
||||
return groupInfo->LockedGetOriginInfo(aOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
QuotaManager::CheckTemporaryStorageLimits()
|
||||
{
|
||||
@ -6135,6 +6309,14 @@ Quota::AllocPQuotaRequestParent(const RequestParams& aParams)
|
||||
actor = new ResetOrClearOp(/* aClear */ false);
|
||||
break;
|
||||
|
||||
case RequestParams::TPersistedParams:
|
||||
actor = new PersistedOp(aParams);
|
||||
break;
|
||||
|
||||
case RequestParams::TPersistParams:
|
||||
actor = new PersistOp(aParams);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
@ -6817,9 +6999,11 @@ ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
|
||||
nsCString suffix;
|
||||
nsCString group;
|
||||
nsCString origin;
|
||||
bool persisted;
|
||||
rv = aQuotaManager->GetDirectoryMetadata2WithRestore(file,
|
||||
persistent,
|
||||
×tamp,
|
||||
&persisted,
|
||||
suffix,
|
||||
group,
|
||||
origin);
|
||||
@ -6981,6 +7165,235 @@ ClearDataOp::GetResponse(RequestResponse& aResponse)
|
||||
aResponse = ClearDataResponse();
|
||||
}
|
||||
|
||||
PersistRequestBase::PersistRequestBase(const PrincipalInfo& aPrincipalInfo)
|
||||
: QuotaRequestBase(/* aExclusive */ false)
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
}
|
||||
|
||||
bool
|
||||
PersistRequestBase::Init(Quota* aQuota)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aQuota);
|
||||
|
||||
if (NS_WARN_IF(!QuotaRequestBase::Init(aQuota))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mPersistenceType.SetValue(PERSISTENCE_TYPE_DEFAULT);
|
||||
|
||||
mNeedsMainThreadInit = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PersistRequestBase::DoInitOnMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(GetState() == State_Initializing);
|
||||
MOZ_ASSERT(mNeedsMainThreadInit);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
PrincipalInfoToPrincipal(mPrincipalInfo, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Figure out which origin we're dealing with.
|
||||
nsCString origin;
|
||||
rv = QuotaManager::GetInfoFromPrincipal(principal, &mSuffix, &mGroup,
|
||||
&origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mOriginScope.SetFromOrigin(origin);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PersistedOp::PersistedOp(const RequestParams& aParams)
|
||||
: PersistRequestBase(aParams.get_PersistedParams().principalInfo())
|
||||
, mPersisted(false)
|
||||
{
|
||||
MOZ_ASSERT(aParams.type() == RequestParams::TPersistedParams);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PersistedOp::DoDirectoryWork(QuotaManager* aQuotaManager)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(!mPersistenceType.IsNull());
|
||||
MOZ_ASSERT(mPersistenceType.Value() == PERSISTENCE_TYPE_DEFAULT);
|
||||
MOZ_ASSERT(mOriginScope.IsOrigin());
|
||||
|
||||
PROFILER_LABEL("Quota", "PersistedOp::DoDirectoryWork",
|
||||
js::ProfileEntry::Category::OTHER);
|
||||
|
||||
Nullable<bool> persisted =
|
||||
aQuotaManager->OriginPersisted(mGroup, mOriginScope.GetOrigin());
|
||||
|
||||
if (!persisted.IsNull()) {
|
||||
mPersisted = persisted.Value();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we get here, it means the origin hasn't been initialized yet.
|
||||
// Try to get the persisted flag from directory metadata on disk.
|
||||
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
nsresult rv = aQuotaManager->GetDirectoryForOrigin(mPersistenceType.Value(),
|
||||
mOriginScope.GetOrigin(),
|
||||
getter_AddRefs(directory));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool exists;
|
||||
rv = directory->Exists(&exists);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (exists) {
|
||||
// Get the persisted flag.
|
||||
bool persisted;
|
||||
rv =
|
||||
aQuotaManager->GetDirectoryMetadata2WithRestore(directory,
|
||||
/* aPersistent */ false,
|
||||
/* aTimestamp */ nullptr,
|
||||
&persisted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mPersisted = persisted;
|
||||
} else {
|
||||
// The directory has not been created yet.
|
||||
mPersisted = false;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PersistedOp::GetResponse(RequestResponse& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
PersistedResponse persistedResponse;
|
||||
persistedResponse.persisted() = mPersisted;
|
||||
|
||||
aResponse = persistedResponse;
|
||||
}
|
||||
|
||||
PersistOp::PersistOp(const RequestParams& aParams)
|
||||
: PersistRequestBase(aParams.get_PersistParams().principalInfo())
|
||||
{
|
||||
MOZ_ASSERT(aParams.type() == RequestParams::TPersistParams);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PersistOp::DoDirectoryWork(QuotaManager* aQuotaManager)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(!mPersistenceType.IsNull());
|
||||
MOZ_ASSERT(mPersistenceType.Value() == PERSISTENCE_TYPE_DEFAULT);
|
||||
MOZ_ASSERT(mOriginScope.IsOrigin());
|
||||
|
||||
PROFILER_LABEL("Quota", "PersistOp::DoDirectoryWork",
|
||||
js::ProfileEntry::Category::OTHER);
|
||||
|
||||
// Update directory metadata on disk first.
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
nsresult rv = aQuotaManager->GetDirectoryForOrigin(mPersistenceType.Value(),
|
||||
mOriginScope.GetOrigin(),
|
||||
getter_AddRefs(directory));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool created;
|
||||
rv = EnsureOriginDirectory(directory, &created);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (created) {
|
||||
rv = CreateDirectoryMetadataFiles(directory,
|
||||
/* aPersisted */ true,
|
||||
mSuffix,
|
||||
mGroup,
|
||||
mOriginScope.GetOrigin(),
|
||||
/* aTimestamp */ nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
// Get the persisted flag (restore the metadata file if necessary).
|
||||
bool persisted;
|
||||
rv =
|
||||
aQuotaManager->GetDirectoryMetadata2WithRestore(directory,
|
||||
/* aPersistent */ false,
|
||||
/* aTimestamp */ nullptr,
|
||||
&persisted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!persisted) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = directory->Clone(getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = file->Append(NS_LITERAL_STRING(METADATA_V2_FILE_NAME));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBinaryOutputStream> stream;
|
||||
rv = GetBinaryOutputStream(file, kUpdateFileFlag, getter_AddRefs(stream));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(stream);
|
||||
|
||||
// Update origin access time while we are here.
|
||||
rv = stream->Write64(PR_Now());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Set the persisted flag to true.
|
||||
rv = stream->WriteBoolean(true);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Directory metadata has been successfully created/updated, try to update
|
||||
// OriginInfo too (it's ok if OriginInfo doesn't exist yet).
|
||||
aQuotaManager->PersistOrigin(mGroup, mOriginScope.GetOrigin());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PersistOp::GetResponse(RequestResponse& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
aResponse = PersistResponse();
|
||||
}
|
||||
|
||||
nsresult
|
||||
StorageDirectoryHelper::GetDirectoryMetadata(nsIFile* aDirectory,
|
||||
int64_t& aTimestamp,
|
||||
@ -8125,6 +8538,7 @@ UpgradeStorageFrom0_0To1_0Helper::ProcessOriginDirectory(
|
||||
|
||||
rv = CreateDirectoryMetadata2(aOriginProps.mDirectory,
|
||||
aOriginProps.mTimestamp,
|
||||
/* aPersisted */ false,
|
||||
aOriginProps.mSuffix,
|
||||
aOriginProps.mGroup,
|
||||
aOriginProps.mOrigin);
|
||||
@ -8407,6 +8821,7 @@ UpgradeStorageFrom1_0To2_0Helper::MaybeStripObsoleteOriginAttributes(
|
||||
|
||||
rv = CreateDirectoryMetadata2(aOriginProps.mDirectory,
|
||||
aOriginProps.mTimestamp,
|
||||
/* aPersisted */ false,
|
||||
aOriginProps.mSuffix,
|
||||
aOriginProps.mGroup,
|
||||
aOriginProps.mOrigin);
|
||||
@ -8478,6 +8893,7 @@ UpgradeStorageFrom1_0To2_0Helper::ProcessOriginDirectory(
|
||||
if (aOriginProps.mNeedsRestore2) {
|
||||
rv = CreateDirectoryMetadata2(aOriginProps.mDirectory,
|
||||
aOriginProps.mTimestamp,
|
||||
/* aPersisted */ false,
|
||||
aOriginProps.mSuffix,
|
||||
aOriginProps.mGroup,
|
||||
aOriginProps.mOrigin);
|
||||
@ -8520,8 +8936,10 @@ RestoreDirectoryMetadata2Helper::ProcessOriginDirectory(
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
// We don't have any approach to restore aPersisted, so reset it to false.
|
||||
nsresult rv = CreateDirectoryMetadata2(aOriginProps.mDirectory,
|
||||
aOriginProps.mTimestamp,
|
||||
/* aPersisted */ false,
|
||||
aOriginProps.mSuffix,
|
||||
aOriginProps.mGroup,
|
||||
aOriginProps.mOrigin);
|
||||
|
@ -59,6 +59,16 @@ struct ResetAllParams
|
||||
{
|
||||
};
|
||||
|
||||
struct PersistedParams
|
||||
{
|
||||
PrincipalInfo principalInfo;
|
||||
};
|
||||
|
||||
struct PersistParams
|
||||
{
|
||||
PrincipalInfo principalInfo;
|
||||
};
|
||||
|
||||
union RequestParams
|
||||
{
|
||||
InitParams;
|
||||
@ -67,6 +77,8 @@ union RequestParams
|
||||
ClearDataParams;
|
||||
ClearAllParams;
|
||||
ResetAllParams;
|
||||
PersistedParams;
|
||||
PersistParams;
|
||||
};
|
||||
|
||||
protocol PQuota
|
||||
|
@ -33,6 +33,15 @@ struct ResetAllResponse
|
||||
{
|
||||
};
|
||||
|
||||
struct PersistedResponse
|
||||
{
|
||||
bool persisted;
|
||||
};
|
||||
|
||||
struct PersistResponse
|
||||
{
|
||||
};
|
||||
|
||||
union RequestResponse
|
||||
{
|
||||
nsresult;
|
||||
@ -42,6 +51,8 @@ union RequestResponse
|
||||
ClearDataResponse;
|
||||
ClearAllResponse;
|
||||
ResetAllResponse;
|
||||
PersistedResponse;
|
||||
PersistResponse;
|
||||
};
|
||||
|
||||
protocol PQuotaRequest
|
||||
|
@ -185,6 +185,14 @@ public:
|
||||
const nsACString& aOrigin,
|
||||
const nsAString& aPath);
|
||||
|
||||
Nullable<bool>
|
||||
OriginPersisted(const nsACString& aGroup,
|
||||
const nsACString& aOrigin);
|
||||
|
||||
void
|
||||
PersistOrigin(const nsACString& aGroup,
|
||||
const nsACString& aOrigin);
|
||||
|
||||
// Called when a process is being shot down. Aborts any running operations
|
||||
// for the given process.
|
||||
void
|
||||
@ -201,6 +209,7 @@ public:
|
||||
nsresult
|
||||
GetDirectoryMetadata2(nsIFile* aDirectory,
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted,
|
||||
nsACString& aSuffix,
|
||||
nsACString& aGroup,
|
||||
nsACString& aOrigin);
|
||||
@ -209,17 +218,21 @@ public:
|
||||
GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
|
||||
bool aPersistent,
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted,
|
||||
nsACString& aSuffix,
|
||||
nsACString& aGroup,
|
||||
nsACString& aOrigin);
|
||||
|
||||
nsresult
|
||||
GetDirectoryMetadata2(nsIFile* aDirectory, int64_t* aTimestamp);
|
||||
GetDirectoryMetadata2(nsIFile* aDirectory,
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted);
|
||||
|
||||
nsresult
|
||||
GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
|
||||
bool aPersistent,
|
||||
int64_t* aTimestamp);
|
||||
int64_t* aTimestamp,
|
||||
bool* aPersisted);
|
||||
|
||||
// This is the main entry point into the QuotaManager API.
|
||||
// Any storage API implementation (quota client) that participates in
|
||||
@ -438,6 +451,11 @@ private:
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin);
|
||||
|
||||
already_AddRefed<OriginInfo>
|
||||
LockedGetOriginInfo(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin);
|
||||
|
||||
nsresult
|
||||
MaybeUpgradeIndexedDBDirectory();
|
||||
|
||||
|
@ -60,6 +60,25 @@ TestingPrefChangedCallback(const char* aPrefName,
|
||||
gTestingMode = Preferences::GetBool(aPrefName);
|
||||
}
|
||||
|
||||
nsresult
|
||||
CheckedPrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
|
||||
PrincipalInfo& aPrincipalInfo)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aPrincipalInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aPrincipalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
|
||||
aPrincipalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class AbortOperationsRunnable final
|
||||
: public Runnable
|
||||
{
|
||||
@ -540,18 +559,12 @@ QuotaManagerService::InitStoragesForPrincipal(
|
||||
|
||||
InitOriginParams params;
|
||||
|
||||
PrincipalInfo& principalInfo = params.principalInfo();
|
||||
|
||||
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
|
||||
nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
|
||||
params.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)) || persistenceType.IsNull()) {
|
||||
@ -585,17 +598,12 @@ QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
|
||||
|
||||
UsageParams params;
|
||||
|
||||
PrincipalInfo& principalInfo = params.principalInfo();
|
||||
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
|
||||
nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
|
||||
params.principalInfo());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
|
||||
principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
params.getGroupUsage() = aGetGroupUsage;
|
||||
|
||||
nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
|
||||
@ -655,18 +663,12 @@ QuotaManagerService::ClearStoragesForPrincipal(nsIPrincipal* aPrincipal,
|
||||
|
||||
ClearOriginParams params;
|
||||
|
||||
PrincipalInfo& principalInfo = params.principalInfo();
|
||||
|
||||
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
|
||||
nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
|
||||
params.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))) {
|
||||
@ -717,6 +719,64 @@ QuotaManagerService::Reset(nsIQuotaRequest** _retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManagerService::Persisted(nsIPrincipal* aPrincipal,
|
||||
nsIQuotaRequest** _retval)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(_retval);
|
||||
|
||||
RefPtr<Request> request = new Request(aPrincipal);
|
||||
|
||||
PersistedParams params;
|
||||
|
||||
nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
|
||||
params.principalInfo());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
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::Persist(nsIPrincipal* aPrincipal,
|
||||
nsIQuotaRequest** _retval)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(_retval);
|
||||
|
||||
RefPtr<Request> request = new Request(aPrincipal);
|
||||
|
||||
PersistParams params;
|
||||
|
||||
nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
|
||||
params.principalInfo());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
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::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
|
@ -100,4 +100,22 @@ interface nsIQuotaManagerService : nsISupports
|
||||
*/
|
||||
[must_use] nsIQuotaRequest
|
||||
reset();
|
||||
|
||||
/**
|
||||
* Check if given origin is persisted.
|
||||
*
|
||||
* @param aPrincipal
|
||||
* A principal for the origin which we want to check.
|
||||
*/
|
||||
[must_use] nsIQuotaRequest
|
||||
persisted(in nsIPrincipal aPrincipal);
|
||||
|
||||
/**
|
||||
* Persist given origin.
|
||||
*
|
||||
* @param aPrincipal
|
||||
* A principal for the origin which we want to persist.
|
||||
*/
|
||||
[must_use] nsIQuotaRequest
|
||||
persist(in nsIPrincipal aPrincipal);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user