зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1840545 - Move QuotaUsageRequestBase to separate files; r=dom-storage-reviewers,jari
Differential Revision: https://phabricator.services.mozilla.com/D182184
This commit is contained in:
Родитель
975bcfb67a
Коммит
b7e8bf5b69
|
@ -19,6 +19,7 @@
|
||||||
#include "OriginInfo.h"
|
#include "OriginInfo.h"
|
||||||
#include "QuotaCommon.h"
|
#include "QuotaCommon.h"
|
||||||
#include "QuotaManager.h"
|
#include "QuotaManager.h"
|
||||||
|
#include "QuotaUsageRequestBase.h"
|
||||||
#include "ResolvableOriginOp.h"
|
#include "ResolvableOriginOp.h"
|
||||||
#include "SanitizationUtils.h"
|
#include "SanitizationUtils.h"
|
||||||
#include "ScopedLogExtraInfo.h"
|
#include "ScopedLogExtraInfo.h"
|
||||||
|
@ -922,36 +923,6 @@ class Quota final : public PQuotaParent {
|
||||||
const ContentParentId& aContentParentId) override;
|
const ContentParentId& aContentParentId) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QuotaUsageRequestBase : public NormalOriginOperationBase,
|
|
||||||
public PQuotaUsageRequestParent {
|
|
||||||
protected:
|
|
||||||
QuotaUsageRequestBase(const char* aRunnableName)
|
|
||||||
: NormalOriginOperationBase(aRunnableName, Nullable<PersistenceType>(),
|
|
||||||
OriginScope::FromNull(),
|
|
||||||
Nullable<Client::Type>(),
|
|
||||||
/* aExclusive */ false) {}
|
|
||||||
|
|
||||||
mozilla::Result<UsageInfo, nsresult> GetUsageForOrigin(
|
|
||||||
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
|
||||||
const OriginMetadata& aOriginMetadata);
|
|
||||||
|
|
||||||
// Subclasses use this override to set the IPDL response value.
|
|
||||||
virtual void GetResponse(UsageRequestResponse& aResponse) = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
mozilla::Result<UsageInfo, nsresult> GetUsageForOriginEntries(
|
|
||||||
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
|
||||||
const OriginMetadata& aOriginMetadata, nsIFile& aDirectory,
|
|
||||||
bool aInitialized);
|
|
||||||
|
|
||||||
void SendResults() override;
|
|
||||||
|
|
||||||
// IPDL methods.
|
|
||||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvCancel() final;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A mix-in class to simplify operations that need to process every origin in
|
// A mix-in class to simplify operations that need to process every origin in
|
||||||
// one or more repositories. Sub-classes should call TraverseRepository in their
|
// one or more repositories. Sub-classes should call TraverseRepository in their
|
||||||
// DoDirectoryWork and implement a ProcessOrigin method for their per-origin
|
// DoDirectoryWork and implement a ProcessOrigin method for their per-origin
|
||||||
|
@ -7676,150 +7647,6 @@ mozilla::ipc::IPCResult Quota::RecvAbortOperationsForProcess(
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<UsageInfo, nsresult> QuotaUsageRequestBase::GetUsageForOrigin(
|
|
||||||
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
|
||||||
const OriginMetadata& aOriginMetadata) {
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
MOZ_ASSERT(aOriginMetadata.mPersistenceType == aPersistenceType);
|
|
||||||
|
|
||||||
QM_TRY_INSPECT(const auto& directory,
|
|
||||||
aQuotaManager.GetOriginDirectory(aOriginMetadata));
|
|
||||||
|
|
||||||
QM_TRY_INSPECT(const bool& exists,
|
|
||||||
MOZ_TO_RESULT_INVOKE_MEMBER(directory, Exists));
|
|
||||||
|
|
||||||
if (!exists || mCanceled) {
|
|
||||||
return UsageInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the directory exists then enumerate all the files inside, adding up
|
|
||||||
// the sizes to get the final usage statistic.
|
|
||||||
bool initialized;
|
|
||||||
|
|
||||||
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
|
||||||
initialized = aQuotaManager.IsOriginInitialized(aOriginMetadata.mOrigin);
|
|
||||||
} else {
|
|
||||||
initialized = aQuotaManager.IsTemporaryStorageInitialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetUsageForOriginEntries(aQuotaManager, aPersistenceType,
|
|
||||||
aOriginMetadata, *directory, initialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<UsageInfo, nsresult> QuotaUsageRequestBase::GetUsageForOriginEntries(
|
|
||||||
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
|
||||||
const OriginMetadata& aOriginMetadata, nsIFile& aDirectory,
|
|
||||||
const bool aInitialized) {
|
|
||||||
AssertIsOnIOThread();
|
|
||||||
|
|
||||||
QM_TRY_RETURN((ReduceEachFileAtomicCancelable(
|
|
||||||
aDirectory, mCanceled, UsageInfo{},
|
|
||||||
[&](UsageInfo oldUsageInfo, const nsCOMPtr<nsIFile>& file)
|
|
||||||
-> mozilla::Result<UsageInfo, nsresult> {
|
|
||||||
QM_TRY_INSPECT(
|
|
||||||
const auto& leafName,
|
|
||||||
MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsAutoString, file, GetLeafName));
|
|
||||||
|
|
||||||
QM_TRY_INSPECT(const auto& dirEntryKind, GetDirEntryKind(*file));
|
|
||||||
|
|
||||||
switch (dirEntryKind) {
|
|
||||||
case nsIFileKind::ExistsAsDirectory: {
|
|
||||||
Client::Type clientType;
|
|
||||||
const bool ok =
|
|
||||||
Client::TypeFromText(leafName, clientType, fallible);
|
|
||||||
if (!ok) {
|
|
||||||
// Unknown directories during getting usage for an origin (even
|
|
||||||
// for an uninitialized origin) are now allowed. Just warn if we
|
|
||||||
// find them.
|
|
||||||
UNKNOWN_FILE_WARNING(leafName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Client* const client = aQuotaManager.GetClient(clientType);
|
|
||||||
MOZ_ASSERT(client);
|
|
||||||
|
|
||||||
QM_TRY_INSPECT(
|
|
||||||
const auto& usageInfo,
|
|
||||||
aInitialized ? client->GetUsageForOrigin(
|
|
||||||
aPersistenceType, aOriginMetadata, mCanceled)
|
|
||||||
: client->InitOrigin(aPersistenceType,
|
|
||||||
aOriginMetadata, mCanceled));
|
|
||||||
return oldUsageInfo + usageInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nsIFileKind::ExistsAsFile:
|
|
||||||
// We are maintaining existing behavior for unknown files here (just
|
|
||||||
// continuing).
|
|
||||||
// This can possibly be used by developers to add temporary backups
|
|
||||||
// into origin directories without losing get usage functionality.
|
|
||||||
if (IsTempMetadata(leafName)) {
|
|
||||||
if (!aInitialized) {
|
|
||||||
QM_TRY(MOZ_TO_RESULT(file->Remove(/* recursive */ false)));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsOriginMetadata(leafName) || IsOSMetadata(leafName) ||
|
|
||||||
IsDotFile(leafName)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unknown files during getting usage for an origin (even for an
|
|
||||||
// uninitialized origin) are now allowed. Just warn if we find them.
|
|
||||||
UNKNOWN_FILE_WARNING(leafName);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nsIFileKind::DoesNotExist:
|
|
||||||
// Ignore files that got removed externally while iterating.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return oldUsageInfo;
|
|
||||||
})));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuotaUsageRequestBase::SendResults() {
|
|
||||||
AssertIsOnOwningThread();
|
|
||||||
|
|
||||||
if (IsActorDestroyed()) {
|
|
||||||
if (NS_SUCCEEDED(mResultCode)) {
|
|
||||||
mResultCode = NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (mCanceled) {
|
|
||||||
mResultCode = NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
UsageRequestResponse response;
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(mResultCode)) {
|
|
||||||
GetResponse(response);
|
|
||||||
} else {
|
|
||||||
response = mResultCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
Unused << PQuotaUsageRequestParent::Send__delete__(this, response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuotaUsageRequestBase::ActorDestroy(ActorDestroyReason aWhy) {
|
|
||||||
AssertIsOnOwningThread();
|
|
||||||
|
|
||||||
NoteActorDestroyed();
|
|
||||||
}
|
|
||||||
|
|
||||||
mozilla::ipc::IPCResult QuotaUsageRequestBase::RecvCancel() {
|
|
||||||
AssertIsOnOwningThread();
|
|
||||||
|
|
||||||
if (mCanceled.exchange(true)) {
|
|
||||||
NS_WARNING("Canceled more than once?!");
|
|
||||||
return IPC_FAIL(this, "Request canceled more than once");
|
|
||||||
}
|
|
||||||
|
|
||||||
return IPC_OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult TraverseRepositoryHelper::TraverseRepository(
|
nsresult TraverseRepositoryHelper::TraverseRepository(
|
||||||
QuotaManager& aQuotaManager, PersistenceType aPersistenceType) {
|
QuotaManager& aQuotaManager, PersistenceType aPersistenceType) {
|
||||||
AssertIsOnIOThread();
|
AssertIsOnIOThread();
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
/* -*- 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 "QuotaUsageRequestBase.h"
|
||||||
|
|
||||||
|
#include "mozilla/dom/quota/Assertions.h"
|
||||||
|
#include "mozilla/dom/quota/CommonMetadata.h"
|
||||||
|
#include "mozilla/dom/quota/FileUtils.h"
|
||||||
|
#include "mozilla/dom/quota/PQuotaRequest.h"
|
||||||
|
#include "mozilla/dom/quota/QuotaCommon.h"
|
||||||
|
#include "mozilla/dom/quota/QuotaManager.h"
|
||||||
|
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||||
|
#include "mozilla/dom/quota/UsageInfo.h"
|
||||||
|
#include "nsIFile.h"
|
||||||
|
|
||||||
|
namespace mozilla::dom::quota {
|
||||||
|
|
||||||
|
Result<UsageInfo, nsresult> QuotaUsageRequestBase::GetUsageForOrigin(
|
||||||
|
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
||||||
|
const OriginMetadata& aOriginMetadata) {
|
||||||
|
AssertIsOnIOThread();
|
||||||
|
MOZ_ASSERT(aOriginMetadata.mPersistenceType == aPersistenceType);
|
||||||
|
|
||||||
|
QM_TRY_INSPECT(const auto& directory,
|
||||||
|
aQuotaManager.GetOriginDirectory(aOriginMetadata));
|
||||||
|
|
||||||
|
QM_TRY_INSPECT(const bool& exists,
|
||||||
|
MOZ_TO_RESULT_INVOKE_MEMBER(directory, Exists));
|
||||||
|
|
||||||
|
if (!exists || mCanceled) {
|
||||||
|
return UsageInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the directory exists then enumerate all the files inside, adding up
|
||||||
|
// the sizes to get the final usage statistic.
|
||||||
|
bool initialized;
|
||||||
|
|
||||||
|
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||||
|
initialized = aQuotaManager.IsOriginInitialized(aOriginMetadata.mOrigin);
|
||||||
|
} else {
|
||||||
|
initialized = aQuotaManager.IsTemporaryStorageInitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetUsageForOriginEntries(aQuotaManager, aPersistenceType,
|
||||||
|
aOriginMetadata, *directory, initialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<UsageInfo, nsresult> QuotaUsageRequestBase::GetUsageForOriginEntries(
|
||||||
|
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
||||||
|
const OriginMetadata& aOriginMetadata, nsIFile& aDirectory,
|
||||||
|
const bool aInitialized) {
|
||||||
|
AssertIsOnIOThread();
|
||||||
|
|
||||||
|
QM_TRY_RETURN((ReduceEachFileAtomicCancelable(
|
||||||
|
aDirectory, mCanceled, UsageInfo{},
|
||||||
|
[&](UsageInfo oldUsageInfo, const nsCOMPtr<nsIFile>& file)
|
||||||
|
-> mozilla::Result<UsageInfo, nsresult> {
|
||||||
|
QM_TRY_INSPECT(
|
||||||
|
const auto& leafName,
|
||||||
|
MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsAutoString, file, GetLeafName));
|
||||||
|
|
||||||
|
QM_TRY_INSPECT(const auto& dirEntryKind, GetDirEntryKind(*file));
|
||||||
|
|
||||||
|
switch (dirEntryKind) {
|
||||||
|
case nsIFileKind::ExistsAsDirectory: {
|
||||||
|
Client::Type clientType;
|
||||||
|
const bool ok =
|
||||||
|
Client::TypeFromText(leafName, clientType, fallible);
|
||||||
|
if (!ok) {
|
||||||
|
// Unknown directories during getting usage for an origin (even
|
||||||
|
// for an uninitialized origin) are now allowed. Just warn if we
|
||||||
|
// find them.
|
||||||
|
UNKNOWN_FILE_WARNING(leafName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Client* const client = aQuotaManager.GetClient(clientType);
|
||||||
|
MOZ_ASSERT(client);
|
||||||
|
|
||||||
|
QM_TRY_INSPECT(
|
||||||
|
const auto& usageInfo,
|
||||||
|
aInitialized ? client->GetUsageForOrigin(
|
||||||
|
aPersistenceType, aOriginMetadata, mCanceled)
|
||||||
|
: client->InitOrigin(aPersistenceType,
|
||||||
|
aOriginMetadata, mCanceled));
|
||||||
|
return oldUsageInfo + usageInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nsIFileKind::ExistsAsFile:
|
||||||
|
// We are maintaining existing behavior for unknown files here (just
|
||||||
|
// continuing).
|
||||||
|
// This can possibly be used by developers to add temporary backups
|
||||||
|
// into origin directories without losing get usage functionality.
|
||||||
|
if (IsTempMetadata(leafName)) {
|
||||||
|
if (!aInitialized) {
|
||||||
|
QM_TRY(MOZ_TO_RESULT(file->Remove(/* recursive */ false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsOriginMetadata(leafName) || IsOSMetadata(leafName) ||
|
||||||
|
IsDotFile(leafName)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown files during getting usage for an origin (even for an
|
||||||
|
// uninitialized origin) are now allowed. Just warn if we find them.
|
||||||
|
UNKNOWN_FILE_WARNING(leafName);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nsIFileKind::DoesNotExist:
|
||||||
|
// Ignore files that got removed externally while iterating.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldUsageInfo;
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuotaUsageRequestBase::SendResults() {
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
if (IsActorDestroyed()) {
|
||||||
|
if (NS_SUCCEEDED(mResultCode)) {
|
||||||
|
mResultCode = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mCanceled) {
|
||||||
|
mResultCode = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsageRequestResponse response;
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(mResultCode)) {
|
||||||
|
GetResponse(response);
|
||||||
|
} else {
|
||||||
|
response = mResultCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unused << PQuotaUsageRequestParent::Send__delete__(this, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuotaUsageRequestBase::ActorDestroy(ActorDestroyReason aWhy) {
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
NoteActorDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult QuotaUsageRequestBase::RecvCancel() {
|
||||||
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
|
if (mCanceled.exchange(true)) {
|
||||||
|
NS_WARNING("Canceled more than once?!");
|
||||||
|
return IPC_FAIL(this, "Request canceled more than once");
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPC_OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mozilla::dom::quota
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* -*- 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 DOM_QUOTA_QUOTAUSAGEREQUESTBASE_H_
|
||||||
|
#define DOM_QUOTA_QUOTAUSAGEREQUESTBASE_H_
|
||||||
|
|
||||||
|
#include "NormalOriginOperationBase.h"
|
||||||
|
#include "mozilla/dom/quota/PQuotaUsageRequestParent.h"
|
||||||
|
|
||||||
|
class nsIFile;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
template <typename V, typename E>
|
||||||
|
class Result;
|
||||||
|
|
||||||
|
namespace dom::quota {
|
||||||
|
|
||||||
|
struct OriginMetadata;
|
||||||
|
class UsageInfo;
|
||||||
|
class UsageRequestResponse;
|
||||||
|
|
||||||
|
class QuotaUsageRequestBase : public NormalOriginOperationBase,
|
||||||
|
public PQuotaUsageRequestParent {
|
||||||
|
protected:
|
||||||
|
QuotaUsageRequestBase(const char* aRunnableName)
|
||||||
|
: NormalOriginOperationBase(aRunnableName, Nullable<PersistenceType>(),
|
||||||
|
OriginScope::FromNull(),
|
||||||
|
Nullable<Client::Type>(),
|
||||||
|
/* aExclusive */ false) {}
|
||||||
|
|
||||||
|
mozilla::Result<UsageInfo, nsresult> GetUsageForOrigin(
|
||||||
|
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
||||||
|
const OriginMetadata& aOriginMetadata);
|
||||||
|
|
||||||
|
// Subclasses use this override to set the IPDL response value.
|
||||||
|
virtual void GetResponse(UsageRequestResponse& aResponse) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mozilla::Result<UsageInfo, nsresult> GetUsageForOriginEntries(
|
||||||
|
QuotaManager& aQuotaManager, PersistenceType aPersistenceType,
|
||||||
|
const OriginMetadata& aOriginMetadata, nsIFile& aDirectory,
|
||||||
|
bool aInitialized);
|
||||||
|
|
||||||
|
void SendResults() override;
|
||||||
|
|
||||||
|
// IPDL methods.
|
||||||
|
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult RecvCancel() final;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom::quota
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // DOM_QUOTA_QUOTAUSAGEREQUESTBASE_H_
|
|
@ -102,6 +102,7 @@ UNIFIED_SOURCES += [
|
||||||
"QuotaObject.cpp",
|
"QuotaObject.cpp",
|
||||||
"QuotaRequests.cpp",
|
"QuotaRequests.cpp",
|
||||||
"QuotaResults.cpp",
|
"QuotaResults.cpp",
|
||||||
|
"QuotaUsageRequestBase.cpp",
|
||||||
"RemoteQuotaObject.cpp",
|
"RemoteQuotaObject.cpp",
|
||||||
"RemoteQuotaObjectChild.cpp",
|
"RemoteQuotaObjectChild.cpp",
|
||||||
"RemoteQuotaObjectParent.cpp",
|
"RemoteQuotaObjectParent.cpp",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче