1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
/* -*- 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 "OriginInfo.h"
#include "GroupInfo.h"
#include "GroupInfoPair.h"
#include "mozilla/dom/quota/AssertionsImpl.h"
#include "mozilla/dom/quota/ResultExtensions.h"
#include "mozilla/dom/quota/UsageInfo.h"
namespace mozilla::dom::quota {
// This constructor is called from the "QuotaManager IO" thread and so we
// can't check if the principal has a WebExtensionPolicy instance associated
// to it, and even besides that if the extension is currently disabled (and so
// no WebExtensionPolicy instance would actually exist) its stored data
// shouldn't be cleared until the extension is uninstalled and so here we
// resort to check the origin scheme instead to initialize mIsExtension.
OriginInfo::OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin,
const nsACString& aStorageOrigin, bool aIsPrivate,
const ClientUsageArray& aClientUsages, uint64_t aUsage,
int64_t aAccessTime, int32_t aMaintenanceDate,
bool aPersisted, bool aDirectoryExists)
: mClientUsages(aClientUsages),
mGroupInfo(aGroupInfo),
mOrigin(aOrigin),
mStorageOrigin(aStorageOrigin),
mUsage(aUsage),
mAccessTime(aAccessTime),
mMaintenanceDate(aMaintenanceDate),
mIsPrivate(aIsPrivate),
mAccessed(false),
mPersisted(aPersisted),
mIsExtension(StringBeginsWith(aOrigin, "moz-extension://"_ns)),
mDirectoryExists(aDirectoryExists) {
MOZ_ASSERT(aGroupInfo);
MOZ_ASSERT_IF(!aIsPrivate, aOrigin == aStorageOrigin);
MOZ_ASSERT_IF(aIsPrivate, aOrigin != aStorageOrigin);
MOZ_ASSERT(aClientUsages.Length() == Client::TypeMax());
MOZ_ASSERT_IF(aPersisted,
aGroupInfo->mPersistenceType == PERSISTENCE_TYPE_DEFAULT);
#ifdef DEBUG
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
uint64_t usage = 0;
for (Client::Type type : quotaManager->AllClientTypes()) {
AssertNoOverflow(usage, aClientUsages[type].valueOr(0));
usage += aClientUsages[type].valueOr(0);
}
MOZ_ASSERT(aUsage == usage);
#endif
MOZ_COUNT_CTOR(OriginInfo);
}
OriginMetadata OriginInfo::FlattenToOriginMetadata() const {
return {mGroupInfo->mGroupInfoPair->Suffix(),
mGroupInfo->mGroupInfoPair->Group(),
mOrigin,
mStorageOrigin,
mIsPrivate,
mGroupInfo->mPersistenceType};
}
OriginStateMetadata OriginInfo::LockedFlattenToOriginStateMetadata() const {
AssertCurrentThreadOwnsQuotaMutex();
return {mAccessTime, mMaintenanceDate, mAccessed, mPersisted};
}
FullOriginMetadata OriginInfo::LockedFlattenToFullOriginMetadata() const {
AssertCurrentThreadOwnsQuotaMutex();
return {FlattenToOriginMetadata(), LockedFlattenToOriginStateMetadata(),
mClientUsages, mUsage, kCurrentQuotaVersion};
}
nsresult OriginInfo::LockedBindToStatement(
mozIStorageStatement* aStatement) const {
AssertCurrentThreadOwnsQuotaMutex();
MOZ_ASSERT(mGroupInfo);
QM_TRY(MOZ_TO_RESULT(aStatement->BindInt32ByName(
"repository_id"_ns, mGroupInfo->mPersistenceType)));
QM_TRY(MOZ_TO_RESULT(aStatement->BindUTF8StringByName(
"suffix"_ns, mGroupInfo->mGroupInfoPair->Suffix())));
QM_TRY(MOZ_TO_RESULT(aStatement->BindUTF8StringByName(
"group_"_ns, mGroupInfo->mGroupInfoPair->Group())));
QM_TRY(MOZ_TO_RESULT(aStatement->BindUTF8StringByName("origin"_ns, mOrigin)));
MOZ_ASSERT(!mIsPrivate);
nsCString clientUsagesText;
mClientUsages.Serialize(clientUsagesText);
QM_TRY(MOZ_TO_RESULT(
aStatement->BindUTF8StringByName("client_usages"_ns, clientUsagesText)));
QM_TRY(MOZ_TO_RESULT(aStatement->BindInt64ByName("usage"_ns, mUsage)));
QM_TRY(MOZ_TO_RESULT(
aStatement->BindInt64ByName("last_access_time"_ns, mAccessTime)));
QM_TRY(MOZ_TO_RESULT(aStatement->BindInt32ByName("last_maintenance_date"_ns,
mMaintenanceDate)));
QM_TRY(MOZ_TO_RESULT(aStatement->BindInt32ByName("accessed"_ns, mAccessed)));
QM_TRY(
MOZ_TO_RESULT(aStatement->BindInt32ByName("persisted"_ns, mPersisted)));
return NS_OK;
}
void OriginInfo::LockedDecreaseUsage(Client::Type aClientType, int64_t aSize) {
AssertCurrentThreadOwnsQuotaMutex();
MOZ_ASSERT(mClientUsages[aClientType].isSome());
AssertNoUnderflow(mClientUsages[aClientType].value(), aSize);
mClientUsages[aClientType] = Some(mClientUsages[aClientType].value() - aSize);
AssertNoUnderflow(mUsage, aSize);
mUsage -= aSize;
if (!LockedPersisted()) {
AssertNoUnderflow(mGroupInfo->mUsage, aSize);
mGroupInfo->mUsage -= aSize;
}
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, aSize);
quotaManager->mTemporaryStorageUsage -= aSize;
}
void OriginInfo::LockedResetUsageForClient(Client::Type aClientType) {
AssertCurrentThreadOwnsQuotaMutex();
uint64_t size = mClientUsages[aClientType].valueOr(0);
mClientUsages[aClientType].reset();
AssertNoUnderflow(mUsage, size);
mUsage -= size;
if (!LockedPersisted()) {
AssertNoUnderflow(mGroupInfo->mUsage, size);
mGroupInfo->mUsage -= size;
}
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, size);
quotaManager->mTemporaryStorageUsage -= size;
}
UsageInfo OriginInfo::LockedGetUsageForClient(Client::Type aClientType) {
AssertCurrentThreadOwnsQuotaMutex();
// The current implementation of this method only supports DOMCACHE and LS,
// which only use DatabaseUsage. If this assertion is lifted, the logic below
// must be adapted.
MOZ_ASSERT(aClientType == Client::Type::DOMCACHE ||
aClientType == Client::Type::LS ||
aClientType == Client::Type::FILESYSTEM);
return UsageInfo{DatabaseUsageType{mClientUsages[aClientType]}};
}
void OriginInfo::LockedPersist() {
AssertCurrentThreadOwnsQuotaMutex();
MOZ_ASSERT(mGroupInfo->mPersistenceType == PERSISTENCE_TYPE_DEFAULT);
MOZ_ASSERT(!mPersisted);
mPersisted = true;
// Remove Usage from GroupInfo
AssertNoUnderflow(mGroupInfo->mUsage, mUsage);
mGroupInfo->mUsage -= mUsage;
}
void OriginInfo::LockedDirectoryCreated() {
AssertCurrentThreadOwnsQuotaMutex();
MOZ_ASSERT(!mDirectoryExists);
mDirectoryExists = true;
}
} // namespace mozilla::dom::quota
|