2012-12-17 23:25:10 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2015-05-03 22:32:37 +03:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-12-17 23:25:10 +04:00
|
|
|
/* 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 mozilla_dom_quota_quotamanager_h__
|
|
|
|
#define mozilla_dom_quota_quotamanager_h__
|
|
|
|
|
|
|
|
#include "QuotaCommon.h"
|
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
#include "mozilla/dom/Nullable.h"
|
2015-06-30 15:59:27 +03:00
|
|
|
#include "mozilla/dom/ipc/IdType.h"
|
2012-12-17 23:25:10 +04:00
|
|
|
#include "mozilla/Mutex.h"
|
2013-09-11 08:18:36 +04:00
|
|
|
|
2013-03-26 15:13:17 +04:00
|
|
|
#include "nsClassHashtable.h"
|
2012-12-17 23:25:10 +04:00
|
|
|
#include "nsRefPtrHashtable.h"
|
|
|
|
|
2019-12-11 11:22:47 +03:00
|
|
|
#include "InitializationTypes.h"
|
2013-03-26 15:13:17 +04:00
|
|
|
#include "Client.h"
|
2013-09-11 08:18:36 +04:00
|
|
|
#include "PersistenceType.h"
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2016-12-01 06:48:32 +03:00
|
|
|
#include "prenv.h"
|
|
|
|
|
2013-03-26 15:13:17 +04:00
|
|
|
#define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
|
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
class mozIStorageConnection;
|
2015-11-22 12:43:55 +03:00
|
|
|
class nsIEventTarget;
|
2013-03-26 15:13:17 +04:00
|
|
|
class nsIPrincipal;
|
|
|
|
class nsIThread;
|
|
|
|
class nsITimer;
|
|
|
|
class nsIURI;
|
2016-01-30 20:05:36 +03:00
|
|
|
class nsPIDOMWindowOuter;
|
2013-09-19 17:54:39 +04:00
|
|
|
class nsIRunnable;
|
2012-12-19 21:45:57 +04:00
|
|
|
|
2018-11-29 23:49:49 +03:00
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
class OriginAttributes;
|
|
|
|
|
2019-02-08 23:01:59 +03:00
|
|
|
namespace ipc {
|
|
|
|
|
|
|
|
class PrincipalInfo;
|
|
|
|
|
|
|
|
} // namespace ipc
|
|
|
|
|
2018-11-29 23:49:49 +03:00
|
|
|
} // namespace mozilla
|
|
|
|
|
2012-12-17 23:25:10 +04:00
|
|
|
BEGIN_QUOTA_NAMESPACE
|
|
|
|
|
2019-08-22 16:06:48 +03:00
|
|
|
class ClientUsageArray;
|
2015-06-30 15:59:53 +03:00
|
|
|
class DirectoryLockImpl;
|
2013-09-11 08:18:36 +04:00
|
|
|
class GroupInfo;
|
2015-01-22 11:40:42 +03:00
|
|
|
class GroupInfoPair;
|
2012-12-17 23:25:10 +04:00
|
|
|
class OriginInfo;
|
2015-06-30 15:59:27 +03:00
|
|
|
class OriginScope;
|
2013-03-26 15:13:17 +04:00
|
|
|
class QuotaObject;
|
2012-12-17 23:25:10 +04:00
|
|
|
|
2015-06-30 15:59:53 +03:00
|
|
|
class NS_NO_VTABLE RefCountedObject {
|
|
|
|
public:
|
2017-01-25 22:51:34 +03:00
|
|
|
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
2015-06-30 15:59:53 +03:00
|
|
|
};
|
|
|
|
|
2015-11-22 12:43:55 +03:00
|
|
|
class DirectoryLock : public RefCountedObject {
|
2015-06-30 15:59:53 +03:00
|
|
|
friend class DirectoryLockImpl;
|
|
|
|
|
2019-03-21 23:08:00 +03:00
|
|
|
public:
|
2019-10-26 11:50:43 +03:00
|
|
|
int64_t Id() const;
|
2019-10-25 15:02:10 +03:00
|
|
|
|
2019-10-26 11:50:43 +03:00
|
|
|
// 'Get' prefix is to avoid name collisions with the enum
|
|
|
|
PersistenceType GetPersistenceType() const;
|
|
|
|
|
|
|
|
const nsACString& Group() const;
|
|
|
|
|
|
|
|
const nsACString& Origin() const;
|
|
|
|
|
|
|
|
Client::Type ClientType() const;
|
2019-10-25 15:02:10 +03:00
|
|
|
|
2019-10-10 17:55:53 +03:00
|
|
|
already_AddRefed<DirectoryLock> Specialize(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin,
|
|
|
|
Client::Type aClientType) const;
|
|
|
|
|
|
|
|
void Log() const;
|
2019-03-21 23:08:00 +03:00
|
|
|
|
2015-06-30 15:59:53 +03:00
|
|
|
private:
|
2020-02-12 13:25:22 +03:00
|
|
|
DirectoryLock() = default;
|
2015-06-30 15:59:53 +03:00
|
|
|
|
2020-02-12 13:25:22 +03:00
|
|
|
~DirectoryLock() = default;
|
2015-06-30 15:59:53 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
class NS_NO_VTABLE OpenDirectoryListener : public RefCountedObject {
|
|
|
|
public:
|
|
|
|
virtual void DirectoryLockAcquired(DirectoryLock* aLock) = 0;
|
|
|
|
|
|
|
|
virtual void DirectoryLockFailed() = 0;
|
|
|
|
|
|
|
|
protected:
|
2020-02-12 13:25:22 +03:00
|
|
|
virtual ~OpenDirectoryListener() = default;
|
2015-06-30 15:59:53 +03:00
|
|
|
};
|
|
|
|
|
2014-11-04 23:44:56 +03:00
|
|
|
struct OriginParams {
|
|
|
|
OriginParams(PersistenceType aPersistenceType, const nsACString& aOrigin)
|
|
|
|
: mOrigin(aOrigin), mPersistenceType(aPersistenceType) {}
|
|
|
|
|
|
|
|
nsCString mOrigin;
|
|
|
|
PersistenceType mPersistenceType;
|
|
|
|
};
|
|
|
|
|
2015-11-22 12:43:55 +03:00
|
|
|
class QuotaManager final : public BackgroundThreadObject {
|
2015-06-30 15:59:53 +03:00
|
|
|
friend class DirectoryLockImpl;
|
2013-09-11 08:18:36 +04:00
|
|
|
friend class GroupInfo;
|
2012-12-17 23:25:10 +04:00
|
|
|
friend class OriginInfo;
|
|
|
|
friend class QuotaObject;
|
2014-09-27 03:21:57 +04:00
|
|
|
|
2019-02-08 23:01:59 +03:00
|
|
|
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
2014-11-04 23:44:56 +03:00
|
|
|
typedef nsClassHashtable<nsCStringHashKey, nsTArray<DirectoryLockImpl*>>
|
2015-06-30 15:59:27 +03:00
|
|
|
DirectoryLockTable;
|
2014-11-04 23:44:56 +03:00
|
|
|
|
2019-02-23 19:12:09 +03:00
|
|
|
class Observer;
|
2015-11-22 12:43:55 +03:00
|
|
|
|
|
|
|
public:
|
|
|
|
NS_INLINE_DECL_REFCOUNTING(QuotaManager)
|
|
|
|
|
2019-02-23 19:12:09 +03:00
|
|
|
static nsresult Initialize();
|
|
|
|
|
2016-12-01 06:48:32 +03:00
|
|
|
static bool IsRunningXPCShellTests() {
|
|
|
|
static bool kRunningXPCShellTests =
|
|
|
|
!!PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
|
|
|
|
return kRunningXPCShellTests;
|
|
|
|
}
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2019-02-07 21:51:22 +03:00
|
|
|
static bool IsRunningGTests() {
|
|
|
|
static bool kRunningGTests = !!PR_GetEnv("MOZ_RUN_GTEST");
|
|
|
|
return kRunningGTests;
|
|
|
|
}
|
|
|
|
|
2015-08-19 21:13:15 +03:00
|
|
|
static const char kReplaceChars[];
|
|
|
|
|
2018-11-29 23:47:30 +03:00
|
|
|
static void GetOrCreate(nsIRunnable* aCallback,
|
|
|
|
nsIEventTarget* aMainEventTarget = nullptr);
|
2012-12-17 23:25:10 +04:00
|
|
|
|
|
|
|
// Returns a non-owning reference.
|
|
|
|
static QuotaManager* Get();
|
|
|
|
|
2013-03-26 15:13:17 +04:00
|
|
|
// Returns true if we've begun the shutdown process.
|
|
|
|
static bool IsShuttingDown();
|
|
|
|
|
2019-02-23 19:30:41 +03:00
|
|
|
static void ShutdownInstance();
|
|
|
|
|
2018-09-20 15:54:42 +03:00
|
|
|
static bool IsOSMetadata(const nsAString& aFileName);
|
|
|
|
|
|
|
|
static bool IsDotFile(const nsAString& aFileName);
|
|
|
|
|
2015-06-30 15:59:27 +03:00
|
|
|
bool IsOriginInitialized(const nsACString& aOrigin) const {
|
|
|
|
AssertIsOnIOThread();
|
|
|
|
|
|
|
|
return mInitializedOrigins.Contains(aOrigin);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsTemporaryStorageInitialized() const {
|
|
|
|
AssertIsOnIOThread();
|
|
|
|
|
|
|
|
return mTemporaryStorageInitialized;
|
|
|
|
}
|
|
|
|
|
2019-05-03 16:03:54 +03:00
|
|
|
/**
|
|
|
|
* For initialization of an origin where the directory already exists. This is
|
|
|
|
* used by EnsureTemporaryStorageIsInitialized/InitializeRepository once it
|
|
|
|
* has tallied origin usage by calling each of the QuotaClient InitOrigin
|
|
|
|
* methods.
|
|
|
|
*/
|
2013-09-11 08:18:36 +04:00
|
|
|
void InitQuotaForOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup, const nsACString& aOrigin,
|
2019-08-22 16:06:48 +03:00
|
|
|
const ClientUsageArray& aClientUsages,
|
2013-09-11 08:18:36 +04:00
|
|
|
uint64_t aUsageBytes, int64_t aAccessTime,
|
2017-01-17 04:41:00 +03:00
|
|
|
bool aPersisted);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-05-03 16:03:54 +03:00
|
|
|
/**
|
|
|
|
* For use in special-cases like LSNG where we need to be able to know that
|
|
|
|
* there is no data stored for an origin. LSNG knows that there is 0 usage for
|
|
|
|
* its storage of an origin and wants to make sure there is a QuotaObject
|
|
|
|
* tracking this. This method will create a non-persisted, 0-usage,
|
|
|
|
* mDirectoryExists=false OriginInfo if there isn't already an OriginInfo. If
|
|
|
|
* an OriginInfo already exists, it will be left as-is, because that implies a
|
|
|
|
* different client has usages for the origin (and there's no need to add
|
|
|
|
* LSNG's 0 usage to the QuotaObject).
|
|
|
|
*/
|
|
|
|
void EnsureQuotaForOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* For use when creating an origin directory. It's possible that origin usage
|
|
|
|
* is already being tracked due to a call to EnsureQuotaForOrigin, and in that
|
2019-05-24 14:26:01 +03:00
|
|
|
* case we need to update the existing OriginInfo rather than create a new
|
|
|
|
* one.
|
2019-05-03 16:03:54 +03:00
|
|
|
*/
|
|
|
|
void NoteOriginDirectoryCreated(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin, bool aPersisted,
|
|
|
|
int64_t& aTimestamp);
|
|
|
|
|
2019-08-22 16:06:48 +03:00
|
|
|
// XXX clients can use QuotaObject instead of calling this method directly.
|
2013-09-11 08:18:36 +04:00
|
|
|
void DecreaseUsageForOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
2019-08-22 16:06:48 +03:00
|
|
|
const nsACString& aOrigin,
|
|
|
|
Client::Type aClientType, int64_t aSize);
|
|
|
|
|
|
|
|
void ResetUsageForClient(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup, const nsACString& aOrigin,
|
|
|
|
Client::Type aClientType);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-08-23 07:46:14 +03:00
|
|
|
bool GetUsageForClient(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup, const nsACString& aOrigin,
|
|
|
|
Client::Type aClientType, uint64_t& aUsage);
|
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
void UpdateOriginAccessTime(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
void RemoveQuota();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
void RemoveQuotaForOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin) {
|
|
|
|
MutexAutoLock lock(mQuotaMutex);
|
|
|
|
LockedRemoveQuotaForOrigin(aPersistenceType, aGroup, aOrigin);
|
|
|
|
}
|
|
|
|
|
2019-08-25 04:34:37 +03:00
|
|
|
nsresult LoadQuota();
|
|
|
|
|
|
|
|
void UnloadQuota();
|
|
|
|
|
2019-08-22 16:06:48 +03:00
|
|
|
already_AddRefed<QuotaObject> GetQuotaObject(
|
|
|
|
PersistenceType aPersistenceType, const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin, Client::Type aClientType, nsIFile* aFile,
|
|
|
|
int64_t aFileSize = -1, int64_t* aFileSizeOut = nullptr);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
already_AddRefed<QuotaObject> GetQuotaObject(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin,
|
2019-08-22 16:06:48 +03:00
|
|
|
Client::Type aClientType,
|
2017-07-10 12:02:44 +03:00
|
|
|
const nsAString& aPath,
|
2018-11-29 23:48:34 +03:00
|
|
|
int64_t aFileSize = -1,
|
2017-07-10 12:02:44 +03:00
|
|
|
int64_t* aFileSizeOut = nullptr);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-10-25 15:02:10 +03:00
|
|
|
already_AddRefed<QuotaObject> GetQuotaObject(const int64_t aDirectoryLockId,
|
|
|
|
const nsAString& aPath);
|
|
|
|
|
2016-08-25 05:19:31 +03:00
|
|
|
Nullable<bool> OriginPersisted(const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-08-25 05:19:31 +03:00
|
|
|
void PersistOrigin(const nsACString& aGroup, const nsACString& aOrigin);
|
|
|
|
|
2015-06-30 15:59:27 +03:00
|
|
|
// Called when a process is being shot down. Aborts any running operations
|
|
|
|
// for the given process.
|
|
|
|
void AbortOperationsForProcess(ContentParentId aContentParentId);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
nsresult GetDirectoryForOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aASCIIOrigin,
|
2013-03-26 15:13:17 +04:00
|
|
|
nsIFile** aDirectory) const;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
nsresult RestoreDirectoryMetadata2(nsIFile* aDirectory, bool aPersistent);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
nsresult GetDirectoryMetadata2(nsIFile* aDirectory, int64_t* aTimestamp,
|
|
|
|
bool* aPersisted, nsACString& aSuffix,
|
2017-03-22 14:14:09 +03:00
|
|
|
nsACString& aGroup, nsACString& aOrigin);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-08-25 05:19:31 +03:00
|
|
|
nsresult GetDirectoryMetadata2WithRestore(
|
2016-06-05 22:42:25 +03:00
|
|
|
nsIFile* aDirectory, bool aPersistent, int64_t* aTimestamp,
|
|
|
|
bool* aPersisted, nsACString& aSuffix, nsACString& aGroup,
|
2019-01-17 20:12:27 +03:00
|
|
|
nsACString& aOrigin, const bool aTelemetry = false);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
nsresult GetDirectoryMetadata2(nsIFile* aDirectory, int64_t* aTimestamp,
|
2016-08-25 05:19:31 +03:00
|
|
|
bool* aPersisted);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
nsresult GetDirectoryMetadata2WithRestore(nsIFile* aDirectory,
|
|
|
|
bool aPersistent,
|
2016-08-25 05:19:31 +03:00
|
|
|
int64_t* aTimestamp,
|
|
|
|
bool* aPersisted);
|
2016-06-05 22:42:25 +03:00
|
|
|
|
2015-06-30 15:59:27 +03:00
|
|
|
// This is the main entry point into the QuotaManager API.
|
|
|
|
// Any storage API implementation (quota client) that participates in
|
|
|
|
// centralized quota and storage handling should call this method to get
|
|
|
|
// a directory lock which will protect client's files from being deleted
|
|
|
|
// while they are still in use.
|
|
|
|
// After a lock is acquired, client is notified via the open listener's
|
|
|
|
// method DirectoryLockAcquired. If the lock couldn't be acquired, client
|
|
|
|
// gets DirectoryLockFailed notification.
|
|
|
|
// A lock is a reference counted object and at the time DirectoryLockAcquired
|
|
|
|
// is called, quota manager holds just one strong reference to it which is
|
|
|
|
// then immediatelly cleared by quota manager. So it's up to client to add
|
|
|
|
// a new reference in order to keep the lock alive.
|
|
|
|
// Unlocking is simply done by dropping all references to the lock object.
|
|
|
|
// In other words, protection which the lock represents dies with the lock
|
|
|
|
// object itself.
|
2020-02-29 07:42:50 +03:00
|
|
|
already_AddRefed<DirectoryLock> OpenDirectory(
|
|
|
|
PersistenceType aPersistenceType, const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin, Client::Type aClientType, bool aExclusive,
|
2020-06-10 13:11:53 +03:00
|
|
|
RefPtr<OpenDirectoryListener> aOpenListener);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
|
|
|
// XXX RemoveMe once bug 1170279 gets fixed.
|
2020-02-29 07:42:50 +03:00
|
|
|
already_AddRefed<DirectoryLock> OpenDirectoryInternal(
|
|
|
|
const Nullable<PersistenceType>& aPersistenceType,
|
|
|
|
const OriginScope& aOriginScope,
|
|
|
|
const Nullable<Client::Type>& aClientType, bool aExclusive,
|
|
|
|
OpenDirectoryListener* aOpenListener);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
|
|
|
// Collect inactive and the least recently used origins.
|
|
|
|
uint64_t CollectOriginsForEviction(
|
2015-10-18 08:24:48 +03:00
|
|
|
uint64_t aMinSizeToBeFreed, nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
2019-05-03 16:03:54 +03:00
|
|
|
/**
|
|
|
|
* Helper method to invoke the provided predicate on all "pending" OriginInfo
|
|
|
|
* instances. These are origins for which the origin directory has not yet
|
|
|
|
* been created but for which quota is already being tracked. This happens,
|
|
|
|
* for example, for the LocalStorage client where an origin that previously
|
|
|
|
* was not using LocalStorage can start issuing writes which it buffers until
|
|
|
|
* eventually flushing them. We defer creating the origin directory for as
|
|
|
|
* long as possible in that case, so the directory won't exist. Logic that
|
|
|
|
* would otherwise only consult the filesystem also needs to use this method.
|
|
|
|
*/
|
|
|
|
template <typename P>
|
|
|
|
void CollectPendingOriginsForListing(P aPredicate);
|
|
|
|
|
2020-02-22 10:57:28 +03:00
|
|
|
bool IsStorageInitialized() const {
|
|
|
|
AssertIsOnIOThread();
|
|
|
|
return static_cast<bool>(mStorageConnection);
|
|
|
|
}
|
|
|
|
|
2017-03-06 20:39:21 +03:00
|
|
|
void AssertStorageIsInitialized() const
|
|
|
|
#ifdef DEBUG
|
|
|
|
;
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
nsresult EnsureStorageIsInitialized();
|
|
|
|
|
2019-11-25 18:04:43 +03:00
|
|
|
nsresult EnsureStorageAndOriginIsInitialized(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aSuffix,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin,
|
|
|
|
Client::Type aClientType,
|
|
|
|
nsIFile** aDirectory);
|
|
|
|
|
|
|
|
nsresult EnsureStorageAndOriginIsInitializedInternal(
|
|
|
|
PersistenceType aPersistenceType, const nsACString& aSuffix,
|
|
|
|
const nsACString& aGroup, const nsACString& aOrigin,
|
|
|
|
const Nullable<Client::Type>& aClientType, nsIFile** aDirectory,
|
|
|
|
bool* aCreated = nullptr);
|
|
|
|
|
|
|
|
nsresult EnsurePersistentOriginIsInitialized(const nsACString& aSuffix,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin,
|
|
|
|
nsIFile** aDirectory,
|
|
|
|
bool* aCreated);
|
|
|
|
|
|
|
|
nsresult EnsureTemporaryOriginIsInitialized(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aSuffix,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin,
|
|
|
|
nsIFile** aDirectory,
|
|
|
|
bool* aCreated);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-08-23 10:56:06 +03:00
|
|
|
nsresult EnsureTemporaryStorageIsInitialized();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2019-08-25 04:34:37 +03:00
|
|
|
void ShutdownStorage();
|
|
|
|
|
2019-04-29 15:23:55 +03:00
|
|
|
nsresult EnsureOriginDirectory(nsIFile* aDirectory, bool* aCreated);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-11-29 23:49:46 +03:00
|
|
|
nsresult AboutToClearOrigins(
|
2017-02-13 20:07:40 +03:00
|
|
|
const Nullable<PersistenceType>& aPersistenceType,
|
2018-11-29 23:49:46 +03:00
|
|
|
const OriginScope& aOriginScope,
|
|
|
|
const Nullable<Client::Type>& aClientType);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
void OriginClearCompleted(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aOrigin,
|
2017-03-06 20:39:33 +03:00
|
|
|
const Nullable<Client::Type>& aClientType);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2015-11-22 12:43:55 +03:00
|
|
|
void StartIdleMaintenance() {
|
|
|
|
AssertIsOnOwningThread();
|
|
|
|
|
|
|
|
for (auto& client : mClients) {
|
|
|
|
client->StartIdleMaintenance();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StopIdleMaintenance() {
|
|
|
|
AssertIsOnOwningThread();
|
|
|
|
|
|
|
|
for (auto& client : mClients) {
|
|
|
|
client->StopIdleMaintenance();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
void AssertCurrentThreadOwnsQuotaMutex() {
|
|
|
|
mQuotaMutex.AssertCurrentThreadOwns();
|
|
|
|
}
|
2013-03-26 15:13:17 +04:00
|
|
|
|
|
|
|
nsIThread* IOThread() {
|
|
|
|
NS_ASSERTION(mIOThread, "This should never be null!");
|
|
|
|
return mIOThread;
|
|
|
|
}
|
|
|
|
|
|
|
|
Client* GetClient(Client::Type aClientType);
|
|
|
|
|
2019-08-23 07:48:36 +03:00
|
|
|
const AutoTArray<Client::Type, Client::TYPE_MAX>& AllClientTypes();
|
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
const nsString& GetBasePath() const { return mBasePath; }
|
|
|
|
|
2020-05-05 09:24:17 +03:00
|
|
|
const nsString& GetStorageName() const { return mStorageName; }
|
|
|
|
|
2014-10-13 23:12:25 +04:00
|
|
|
const nsString& GetStoragePath() const { return mStoragePath; }
|
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
const nsString& GetStoragePath(PersistenceType aPersistenceType) const {
|
|
|
|
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
2014-11-28 11:44:12 +03:00
|
|
|
return mPermanentStoragePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aPersistenceType == PERSISTENCE_TYPE_TEMPORARY) {
|
|
|
|
return mTemporaryStoragePath;
|
2013-09-11 08:18:36 +04:00
|
|
|
}
|
|
|
|
|
2014-11-28 11:44:12 +03:00
|
|
|
MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
|
2013-09-11 08:18:36 +04:00
|
|
|
|
2014-11-28 11:44:12 +03:00
|
|
|
return mDefaultStoragePath;
|
2013-09-11 08:18:36 +04:00
|
|
|
}
|
|
|
|
|
2014-05-21 02:19:59 +04:00
|
|
|
uint64_t GetGroupLimit() const;
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2019-08-22 23:51:09 +03:00
|
|
|
uint64_t GetGroupUsage(const nsACString& aGroup);
|
|
|
|
|
|
|
|
uint64_t GetOriginUsage(const nsACString& aGroup, const nsACString& aOrigin);
|
2016-06-24 05:24:06 +03:00
|
|
|
|
2017-09-06 12:25:13 +03:00
|
|
|
void NotifyStoragePressure(uint64_t aUsage);
|
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
static void GetStorageId(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aOrigin, Client::Type aClientType,
|
2013-11-25 20:53:48 +04:00
|
|
|
nsACString& aDatabaseId);
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2019-02-08 23:01:59 +03:00
|
|
|
static bool IsPrincipalInfoValid(const PrincipalInfo& aPrincipalInfo);
|
|
|
|
|
2019-02-08 23:02:23 +03:00
|
|
|
static void GetInfoFromValidatedPrincipalInfo(
|
|
|
|
const PrincipalInfo& aPrincipalInfo, nsACString* aSuffix,
|
|
|
|
nsACString* aGroup, nsACString* aOrigin);
|
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
static nsresult GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
|
2016-06-05 22:42:25 +03:00
|
|
|
nsACString* aSuffix, nsACString* aGroup,
|
2017-03-06 20:38:42 +03:00
|
|
|
nsACString* aOrigin);
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2016-01-30 20:05:36 +03:00
|
|
|
static nsresult GetInfoFromWindow(nsPIDOMWindowOuter* aWindow,
|
2016-06-05 22:42:25 +03:00
|
|
|
nsACString* aSuffix, nsACString* aGroup,
|
2017-03-06 20:38:42 +03:00
|
|
|
nsACString* aOrigin);
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
static void GetInfoForChrome(nsACString* aSuffix, nsACString* aGroup,
|
2017-03-06 20:38:42 +03:00
|
|
|
nsACString* aOrigin);
|
2014-11-04 23:44:56 +03:00
|
|
|
|
2017-03-22 14:14:09 +03:00
|
|
|
static bool IsOriginInternal(const nsACString& aOrigin);
|
2015-01-09 18:56:23 +03:00
|
|
|
|
2014-09-27 03:21:57 +04:00
|
|
|
static void ChromeOrigin(nsACString& aOrigin);
|
|
|
|
|
2017-03-06 20:40:37 +03:00
|
|
|
static bool AreOriginsEqualOnDisk(nsACString& aOrigin1, nsACString& aOrigin2);
|
|
|
|
|
2018-11-29 23:49:49 +03:00
|
|
|
static bool ParseOrigin(const nsACString& aOrigin, nsCString& aSpec,
|
|
|
|
OriginAttributes* aAttrs);
|
|
|
|
|
2019-08-25 03:45:19 +03:00
|
|
|
static void InvalidateQuotaCache();
|
|
|
|
|
2012-12-19 21:45:57 +04:00
|
|
|
private:
|
2020-05-05 09:24:17 +03:00
|
|
|
QuotaManager(const nsAString& aBasePath, const nsAString& aStorageName);
|
2012-12-19 21:45:57 +04:00
|
|
|
|
|
|
|
virtual ~QuotaManager();
|
|
|
|
|
2020-05-05 09:24:17 +03:00
|
|
|
nsresult Init();
|
2015-11-22 12:43:55 +03:00
|
|
|
|
|
|
|
void Shutdown();
|
2012-12-19 21:45:57 +04:00
|
|
|
|
2015-06-30 15:59:27 +03:00
|
|
|
already_AddRefed<DirectoryLockImpl> CreateDirectoryLock(
|
2017-02-13 20:07:40 +03:00
|
|
|
const Nullable<PersistenceType>& aPersistenceType,
|
2015-06-30 15:59:27 +03:00
|
|
|
const nsACString& aGroup, const OriginScope& aOriginScope,
|
2017-02-13 20:07:40 +03:00
|
|
|
const Nullable<Client::Type>& aClientType, bool aExclusive,
|
2020-06-10 13:11:53 +03:00
|
|
|
bool aInternal, RefPtr<OpenDirectoryListener> aOpenListener,
|
|
|
|
bool& aBlockedOut);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
|
|
|
already_AddRefed<DirectoryLockImpl> CreateDirectoryLockForEviction(
|
|
|
|
PersistenceType aPersistenceType, const nsACString& aGroup,
|
2017-03-06 20:38:42 +03:00
|
|
|
const nsACString& aOrigin);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
2020-06-10 13:11:53 +03:00
|
|
|
void RegisterDirectoryLock(DirectoryLockImpl& aLock);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
2020-06-10 13:11:53 +03:00
|
|
|
void UnregisterDirectoryLock(DirectoryLockImpl& aLock);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
2020-06-10 13:11:53 +03:00
|
|
|
void RemovePendingDirectoryLock(DirectoryLockImpl& aLock);
|
2015-06-30 15:59:27 +03:00
|
|
|
|
2015-06-30 15:59:42 +03:00
|
|
|
uint64_t LockedCollectOriginsForEviction(
|
2015-10-18 08:24:48 +03:00
|
|
|
uint64_t aMinSizeToBeFreed, nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
|
2013-09-11 08:18:36 +04:00
|
|
|
|
|
|
|
void LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin);
|
|
|
|
|
2019-05-03 16:03:54 +03:00
|
|
|
already_AddRefed<GroupInfo> LockedGetOrCreateGroupInfo(
|
|
|
|
PersistenceType aPersistenceType, const nsACString& aGroup);
|
|
|
|
|
2016-08-25 05:19:31 +03:00
|
|
|
already_AddRefed<OriginInfo> LockedGetOriginInfo(
|
|
|
|
PersistenceType aPersistenceType, const nsACString& aGroup,
|
|
|
|
const nsACString& aOrigin);
|
|
|
|
|
2020-03-11 15:51:26 +03:00
|
|
|
nsresult UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
|
|
|
|
nsIFile* aIndexedDBDir);
|
2013-09-11 08:18:36 +04:00
|
|
|
|
2020-03-11 15:51:26 +03:00
|
|
|
nsresult UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
|
|
|
|
nsIFile* aPersistentStorageDir);
|
2014-11-28 11:44:12 +03:00
|
|
|
|
2018-10-17 16:37:16 +03:00
|
|
|
template <typename Helper>
|
|
|
|
nsresult UpgradeStorage(const int32_t aOldVersion, const int32_t aNewVersion,
|
|
|
|
mozIStorageConnection* aConnection);
|
|
|
|
|
2017-01-10 13:44:32 +03:00
|
|
|
nsresult UpgradeStorageFrom0_0To1_0(mozIStorageConnection* aConnection);
|
2016-06-05 22:42:25 +03:00
|
|
|
|
2017-01-10 13:44:32 +03:00
|
|
|
nsresult UpgradeStorageFrom1_0To2_0(mozIStorageConnection* aConnection);
|
2014-11-28 11:44:12 +03:00
|
|
|
|
2017-10-03 17:02:27 +03:00
|
|
|
nsresult UpgradeStorageFrom2_0To2_1(mozIStorageConnection* aConnection);
|
2017-07-18 13:54:20 +03:00
|
|
|
|
2019-03-20 16:31:10 +03:00
|
|
|
nsresult UpgradeStorageFrom2_1To2_2(mozIStorageConnection* aConnection);
|
|
|
|
|
2019-08-25 04:34:37 +03:00
|
|
|
nsresult UpgradeStorageFrom2_2To2_3(mozIStorageConnection* aConnection);
|
|
|
|
|
2018-06-29 10:58:09 +03:00
|
|
|
nsresult MaybeRemoveLocalStorageData();
|
|
|
|
|
|
|
|
nsresult MaybeRemoveLocalStorageDirectories();
|
|
|
|
|
2019-04-25 12:25:52 +03:00
|
|
|
nsresult CreateLocalStorageArchiveConnectionFromWebAppsStore(
|
|
|
|
mozIStorageConnection** aConnection);
|
|
|
|
|
|
|
|
nsresult CreateLocalStorageArchiveConnection(
|
|
|
|
mozIStorageConnection** aConnection, bool& aNewlyCreated);
|
|
|
|
|
|
|
|
nsresult RecreateLocalStorageArchive(
|
|
|
|
nsCOMPtr<mozIStorageConnection>& aConnection);
|
|
|
|
|
|
|
|
nsresult DowngradeLocalStorageArchive(
|
|
|
|
nsCOMPtr<mozIStorageConnection>& aConnection);
|
|
|
|
|
2019-05-07 13:54:02 +03:00
|
|
|
nsresult UpgradeLocalStorageArchiveFromLessThan4To4(
|
2019-04-25 12:25:52 +03:00
|
|
|
nsCOMPtr<mozIStorageConnection>& aConnection);
|
|
|
|
|
2019-05-07 13:54:02 +03:00
|
|
|
/*
|
|
|
|
nsresult UpgradeLocalStorageArchiveFrom4To5();
|
|
|
|
*/
|
2019-04-29 07:10:42 +03:00
|
|
|
|
2014-11-04 23:44:56 +03:00
|
|
|
nsresult InitializeRepository(PersistenceType aPersistenceType);
|
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
nsresult InitializeOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aGroup, const nsACString& aOrigin,
|
|
|
|
int64_t aAccessTime, bool aPersisted,
|
|
|
|
nsIFile* aDirectory);
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2013-09-11 08:18:36 +04:00
|
|
|
void CheckTemporaryStorageLimits();
|
|
|
|
|
2014-11-04 23:44:56 +03:00
|
|
|
void DeleteFilesForOrigin(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aOrigin);
|
2013-09-11 08:18:36 +04:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
void FinalizeOriginEviction(nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2013-06-05 12:11:23 +04:00
|
|
|
void ReleaseIOThreadObjects() {
|
|
|
|
AssertIsOnIOThread();
|
|
|
|
|
2019-08-23 07:48:36 +03:00
|
|
|
for (Client::Type type : AllClientTypes()) {
|
|
|
|
mClients[type]->ReleaseIOThreadObjects();
|
2013-06-05 12:11:23 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-30 15:59:27 +03:00
|
|
|
DirectoryLockTable& GetDirectoryLockTable(PersistenceType aPersistenceType);
|
2014-11-04 23:44:56 +03:00
|
|
|
|
2018-08-15 17:59:26 +03:00
|
|
|
bool IsSanitizedOriginValid(const nsACString& aSanitizedOrigin);
|
|
|
|
|
2019-10-25 15:02:10 +03:00
|
|
|
int64_t GenerateDirectoryLockId();
|
|
|
|
|
2015-11-22 12:43:55 +03:00
|
|
|
static void ShutdownTimerCallback(nsITimer* aTimer, void* aClosure);
|
|
|
|
|
2019-08-25 04:34:37 +03:00
|
|
|
// Thread on which IO is performed.
|
|
|
|
nsCOMPtr<nsIThread> mIOThread;
|
|
|
|
|
|
|
|
nsCOMPtr<mozIStorageConnection> mStorageConnection;
|
|
|
|
|
|
|
|
// A timer that gets activated at shutdown to ensure we close all storages.
|
|
|
|
nsCOMPtr<nsITimer> mShutdownTimer;
|
|
|
|
|
2012-12-17 23:25:10 +04:00
|
|
|
mozilla::Mutex mQuotaMutex;
|
|
|
|
|
2015-01-22 11:40:42 +03:00
|
|
|
nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2015-06-30 15:59:27 +03:00
|
|
|
// Maintains a list of directory locks that are queued.
|
2015-10-18 08:24:48 +03:00
|
|
|
nsTArray<RefPtr<DirectoryLockImpl>> mPendingDirectoryLocks;
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2019-10-25 15:02:10 +03:00
|
|
|
// Maintains a list of directory locks that are acquired or queued. It can be
|
|
|
|
// accessed on the owning (PBackground) thread only.
|
2015-06-30 15:59:27 +03:00
|
|
|
nsTArray<DirectoryLockImpl*> mDirectoryLocks;
|
2014-11-04 23:44:56 +03:00
|
|
|
|
2019-10-25 15:02:10 +03:00
|
|
|
// Only modifed on the owning thread, but read on multiple threads. Therefore
|
|
|
|
// all modifications (including those on the owning thread) and all reads off
|
|
|
|
// the owning thread must be protected by mQuotaMutex. In other words, only
|
|
|
|
// reads on the owning thread don't have to be protected by mQuotaMutex.
|
|
|
|
nsDataHashtable<nsUint64HashKey, DirectoryLockImpl*> mDirectoryLockIdTable;
|
|
|
|
|
2015-06-30 15:59:27 +03:00
|
|
|
// Directory lock tables that are used to update origin access time.
|
|
|
|
DirectoryLockTable mTemporaryDirectoryLockTable;
|
|
|
|
DirectoryLockTable mDefaultDirectoryLockTable;
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2018-08-15 17:59:26 +03:00
|
|
|
// A list of all successfully initialized persistent origins. This list isn't
|
|
|
|
// protected by any mutex but it is only ever touched on the IO thread.
|
2013-03-26 15:13:17 +04:00
|
|
|
nsTArray<nsCString> mInitializedOrigins;
|
|
|
|
|
2018-08-15 17:59:26 +03:00
|
|
|
// A hash table that is used to cache origin parser results for given
|
|
|
|
// sanitized origin strings. This hash table isn't protected by any mutex but
|
|
|
|
// it is only ever touched on the IO thread.
|
|
|
|
nsDataHashtable<nsCStringHashKey, bool> mValidOrigins;
|
|
|
|
|
2019-12-09 21:47:56 +03:00
|
|
|
struct OriginInitializationInfo {
|
|
|
|
bool mPersistentOriginAttempted : 1;
|
|
|
|
bool mTemporaryOriginAttempted : 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
// A hash table that is currently used to track origin initialization
|
|
|
|
// attempts. This hash table isn't protected by any mutex but it is only ever
|
|
|
|
// touched on the IO thread.
|
|
|
|
nsDataHashtable<nsCStringHashKey, OriginInitializationInfo>
|
|
|
|
mOriginInitializationInfos;
|
2019-12-11 11:20:46 +03:00
|
|
|
|
2016-07-18 19:51:54 +03:00
|
|
|
// This array is populated at initialization time and then never modified, so
|
|
|
|
// it can be iterated on any thread.
|
2016-02-02 18:36:30 +03:00
|
|
|
AutoTArray<RefPtr<Client>, Client::TYPE_MAX> mClients;
|
2013-03-26 15:13:17 +04:00
|
|
|
|
2019-08-23 07:48:36 +03:00
|
|
|
AutoTArray<Client::Type, Client::TYPE_MAX> mAllClientTypes;
|
|
|
|
AutoTArray<Client::Type, Client::TYPE_MAX> mAllClientTypesExceptLS;
|
|
|
|
|
2019-12-11 11:22:47 +03:00
|
|
|
InitializationInfo mInitializationInfo;
|
|
|
|
|
2016-06-05 22:42:25 +03:00
|
|
|
nsString mBasePath;
|
2020-05-05 09:24:17 +03:00
|
|
|
nsString mStorageName;
|
2013-09-11 08:18:36 +04:00
|
|
|
nsString mIndexedDBPath;
|
2014-10-13 23:12:25 +04:00
|
|
|
nsString mStoragePath;
|
2014-11-28 11:44:12 +03:00
|
|
|
nsString mPermanentStoragePath;
|
2013-09-11 08:18:36 +04:00
|
|
|
nsString mTemporaryStoragePath;
|
2014-11-28 11:44:12 +03:00
|
|
|
nsString mDefaultStoragePath;
|
2013-09-11 08:18:36 +04:00
|
|
|
|
|
|
|
uint64_t mTemporaryStorageLimit;
|
|
|
|
uint64_t mTemporaryStorageUsage;
|
2019-10-25 15:02:10 +03:00
|
|
|
int64_t mNextDirectoryLockId;
|
2013-09-11 08:18:36 +04:00
|
|
|
bool mTemporaryStorageInitialized;
|
2019-08-25 04:34:37 +03:00
|
|
|
bool mCacheUsable;
|
2012-12-19 21:45:57 +04:00
|
|
|
};
|
|
|
|
|
2012-12-17 23:25:10 +04:00
|
|
|
END_QUOTA_NAMESPACE
|
|
|
|
|
|
|
|
#endif /* mozilla_dom_quota_quotamanager_h__ */
|