1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "OriginInfo.h"
10 #include "GroupInfoPair.h"
11 #include "mozilla/dom/quota/AssertionsImpl.h"
12 #include "mozilla/dom/quota/ResultExtensions.h"
13 #include "mozilla/dom/quota/UsageInfo.h"
15 namespace mozilla::dom::quota
{
17 OriginInfo::OriginInfo(GroupInfo
* aGroupInfo
, const nsACString
& aOrigin
,
18 const nsACString
& aStorageOrigin
, bool aIsPrivate
,
19 const ClientUsageArray
& aClientUsages
, uint64_t aUsage
,
20 int64_t aAccessTime
, bool aPersisted
,
21 bool aDirectoryExists
)
22 : mClientUsages(aClientUsages
.Clone()),
23 mGroupInfo(aGroupInfo
),
25 mStorageOrigin(aStorageOrigin
),
27 mAccessTime(aAccessTime
),
28 mIsPrivate(aIsPrivate
),
30 mPersisted(aPersisted
),
31 mDirectoryExists(aDirectoryExists
) {
32 MOZ_ASSERT(aGroupInfo
);
33 MOZ_ASSERT_IF(!aIsPrivate
, aOrigin
== aStorageOrigin
);
34 MOZ_ASSERT_IF(aIsPrivate
, aOrigin
!= aStorageOrigin
);
35 MOZ_ASSERT(aClientUsages
.Length() == Client::TypeMax());
36 MOZ_ASSERT_IF(aPersisted
,
37 aGroupInfo
->mPersistenceType
== PERSISTENCE_TYPE_DEFAULT
);
39 // This constructor is called from the "QuotaManager IO" thread and so
40 // we can't check if the principal has a WebExtensionPolicy instance
41 // associated to it, and even besides that if the extension is currently
42 // disabled (and so no WebExtensionPolicy instance would actually exist)
43 // its stored data shouldn't be cleared until the extension is uninstalled
44 // and so here we resort to check the origin scheme instead.
45 mIsExtension
= StringBeginsWith(mOrigin
, "moz-extension://"_ns
);
48 QuotaManager
* quotaManager
= QuotaManager::Get();
49 MOZ_ASSERT(quotaManager
);
52 for (Client::Type type
: quotaManager
->AllClientTypes()) {
53 AssertNoOverflow(usage
, aClientUsages
[type
].valueOr(0));
54 usage
+= aClientUsages
[type
].valueOr(0);
56 MOZ_ASSERT(aUsage
== usage
);
59 MOZ_COUNT_CTOR(OriginInfo
);
62 OriginMetadata
OriginInfo::FlattenToOriginMetadata() const {
63 return {mGroupInfo
->mGroupInfoPair
->Suffix(),
64 mGroupInfo
->mGroupInfoPair
->Group(),
68 mGroupInfo
->mPersistenceType
};
71 FullOriginMetadata
OriginInfo::LockedFlattenToFullOriginMetadata() const {
72 AssertCurrentThreadOwnsQuotaMutex();
74 return {FlattenToOriginMetadata(), mPersisted
, mAccessTime
};
77 nsresult
OriginInfo::LockedBindToStatement(
78 mozIStorageStatement
* aStatement
) const {
79 AssertCurrentThreadOwnsQuotaMutex();
80 MOZ_ASSERT(mGroupInfo
);
82 QM_TRY(MOZ_TO_RESULT(aStatement
->BindInt32ByName(
83 "repository_id"_ns
, mGroupInfo
->mPersistenceType
)));
85 QM_TRY(MOZ_TO_RESULT(aStatement
->BindUTF8StringByName(
86 "suffix"_ns
, mGroupInfo
->mGroupInfoPair
->Suffix())));
87 QM_TRY(MOZ_TO_RESULT(aStatement
->BindUTF8StringByName(
88 "group_"_ns
, mGroupInfo
->mGroupInfoPair
->Group())));
89 QM_TRY(MOZ_TO_RESULT(aStatement
->BindUTF8StringByName("origin"_ns
, mOrigin
)));
91 MOZ_ASSERT(!mIsPrivate
);
93 nsCString clientUsagesText
;
94 mClientUsages
.Serialize(clientUsagesText
);
97 aStatement
->BindUTF8StringByName("client_usages"_ns
, clientUsagesText
)));
98 QM_TRY(MOZ_TO_RESULT(aStatement
->BindInt64ByName("usage"_ns
, mUsage
)));
100 aStatement
->BindInt64ByName("last_access_time"_ns
, mAccessTime
)));
101 QM_TRY(MOZ_TO_RESULT(aStatement
->BindInt32ByName("accessed"_ns
, mAccessed
)));
103 MOZ_TO_RESULT(aStatement
->BindInt32ByName("persisted"_ns
, mPersisted
)));
108 void OriginInfo::LockedDecreaseUsage(Client::Type aClientType
, int64_t aSize
) {
109 AssertCurrentThreadOwnsQuotaMutex();
111 MOZ_ASSERT(mClientUsages
[aClientType
].isSome());
112 AssertNoUnderflow(mClientUsages
[aClientType
].value(), aSize
);
113 mClientUsages
[aClientType
] = Some(mClientUsages
[aClientType
].value() - aSize
);
115 AssertNoUnderflow(mUsage
, aSize
);
118 if (!LockedPersisted()) {
119 AssertNoUnderflow(mGroupInfo
->mUsage
, aSize
);
120 mGroupInfo
->mUsage
-= aSize
;
123 QuotaManager
* quotaManager
= QuotaManager::Get();
124 MOZ_ASSERT(quotaManager
);
126 AssertNoUnderflow(quotaManager
->mTemporaryStorageUsage
, aSize
);
127 quotaManager
->mTemporaryStorageUsage
-= aSize
;
130 void OriginInfo::LockedResetUsageForClient(Client::Type aClientType
) {
131 AssertCurrentThreadOwnsQuotaMutex();
133 uint64_t size
= mClientUsages
[aClientType
].valueOr(0);
135 mClientUsages
[aClientType
].reset();
137 AssertNoUnderflow(mUsage
, size
);
140 if (!LockedPersisted()) {
141 AssertNoUnderflow(mGroupInfo
->mUsage
, size
);
142 mGroupInfo
->mUsage
-= size
;
145 QuotaManager
* quotaManager
= QuotaManager::Get();
146 MOZ_ASSERT(quotaManager
);
148 AssertNoUnderflow(quotaManager
->mTemporaryStorageUsage
, size
);
149 quotaManager
->mTemporaryStorageUsage
-= size
;
152 UsageInfo
OriginInfo::LockedGetUsageForClient(Client::Type aClientType
) {
153 AssertCurrentThreadOwnsQuotaMutex();
155 // The current implementation of this method only supports DOMCACHE and LS,
156 // which only use DatabaseUsage. If this assertion is lifted, the logic below
158 MOZ_ASSERT(aClientType
== Client::Type::DOMCACHE
||
159 aClientType
== Client::Type::LS
||
160 aClientType
== Client::Type::FILESYSTEM
);
162 return UsageInfo
{DatabaseUsageType
{mClientUsages
[aClientType
]}};
165 void OriginInfo::LockedPersist() {
166 AssertCurrentThreadOwnsQuotaMutex();
167 MOZ_ASSERT(mGroupInfo
->mPersistenceType
== PERSISTENCE_TYPE_DEFAULT
);
168 MOZ_ASSERT(!mPersisted
);
172 // Remove Usage from GroupInfo
173 AssertNoUnderflow(mGroupInfo
->mUsage
, mUsage
);
174 mGroupInfo
->mUsage
-= mUsage
;
177 } // namespace mozilla::dom::quota