зеркало из https://github.com/mozilla/gecko-dev.git
Bug 934640 - Implement IDBFactory.databases() to enumerate IndexedDB databases; r=dom-storage-reviewers,asuth
Differential Revision: https://phabricator.services.mozilla.com/D190053
This commit is contained in:
Родитель
bf65876240
Коммит
504e95b43b
|
@ -94,6 +94,7 @@
|
|||
#include "mozilla/dom/FileBlobImpl.h"
|
||||
#include "mozilla/dom/FlippedOnce.h"
|
||||
#include "mozilla/dom/IDBCursorBinding.h"
|
||||
#include "mozilla/dom/IDBFactory.h"
|
||||
#include "mozilla/dom/IPCBlob.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/dom/IndexedDatabase.h"
|
||||
|
@ -2147,6 +2148,14 @@ class Factory final : public PBackgroundIDBFactoryParent,
|
|||
|
||||
bool DeallocPBackgroundIDBFactoryRequestParent(
|
||||
PBackgroundIDBFactoryRequestParent* aActor) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvGetDatabases(
|
||||
const PersistenceType& aPersistenceType,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
GetDatabasesResolver&& aResolve) override;
|
||||
|
||||
private:
|
||||
Maybe<ContentParentId> GetContentParentId() const;
|
||||
};
|
||||
|
||||
class WaitForTransactionsHelper final : public Runnable {
|
||||
|
@ -3354,6 +3363,40 @@ class DeleteDatabaseOp::VersionChangeOp final : public DatabaseOperationBase {
|
|||
NS_DECL_NSIRUNNABLE
|
||||
};
|
||||
|
||||
class GetDatabasesOp final : public FactoryOp {
|
||||
nsTArray<DatabaseMetadata> mDatabaseMetadataArray;
|
||||
Factory::GetDatabasesResolver mResolver;
|
||||
|
||||
public:
|
||||
GetDatabasesOp(SafeRefPtr<Factory> aFactory,
|
||||
const Maybe<ContentParentId>& aContentParentId,
|
||||
const PersistenceType aPersistenceType,
|
||||
const PrincipalInfo& aPrincipalInfo,
|
||||
Factory::GetDatabasesResolver&& aResolver)
|
||||
: FactoryOp(std::move(aFactory), aContentParentId, aPersistenceType,
|
||||
aPrincipalInfo, Nothing(), /* aDeleting */ false),
|
||||
mResolver(std::move(aResolver)) {}
|
||||
|
||||
private:
|
||||
~GetDatabasesOp() override = default;
|
||||
|
||||
nsresult DatabasesNotAvailable();
|
||||
|
||||
nsresult DatabaseOpen() override;
|
||||
|
||||
nsresult DoDatabaseWork() override;
|
||||
|
||||
nsresult BeginVersionChange() override;
|
||||
|
||||
bool AreActorsAlive() override;
|
||||
|
||||
void SendBlockedNotification() override;
|
||||
|
||||
nsresult DispatchToWorkThread() override;
|
||||
|
||||
void SendResults() override;
|
||||
};
|
||||
|
||||
class VersionChangeTransactionOp : public TransactionDatabaseOperationBase {
|
||||
public:
|
||||
void Cleanup() override;
|
||||
|
@ -4732,6 +4775,8 @@ class DatabaseLoggingInfo final {
|
|||
};
|
||||
|
||||
class QuotaClient final : public mozilla::dom::quota::Client {
|
||||
friend class GetDatabasesOp;
|
||||
|
||||
static QuotaClient* sInstance;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> mBackgroundThread;
|
||||
|
@ -4865,8 +4910,9 @@ class QuotaClient final : public mozilla::dom::quota::Client {
|
|||
// checks those unfinished deletion and clean them up after that.
|
||||
template <ObsoleteFilenamesHandling ObsoleteFilenames =
|
||||
ObsoleteFilenamesHandling::Omit>
|
||||
Result<GetDatabaseFilenamesResult<ObsoleteFilenames>, nsresult>
|
||||
GetDatabaseFilenames(nsIFile& aDirectory, const AtomicBool& aCanceled);
|
||||
Result<GetDatabaseFilenamesResult<ObsoleteFilenames>,
|
||||
nsresult> static GetDatabaseFilenames(nsIFile& aDirectory,
|
||||
const AtomicBool& aCanceled);
|
||||
|
||||
nsresult GetUsageForOriginInternal(PersistenceType aPersistenceType,
|
||||
const OriginMetadata& aOriginMetadata,
|
||||
|
@ -9172,18 +9218,7 @@ Factory::AllocPBackgroundIDBFactoryRequestParent(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Maybe<ContentParentId> contentParentId;
|
||||
|
||||
uint64_t childID = BackgroundParent::GetChildID(Manager());
|
||||
if (childID) {
|
||||
// If childID is not zero we are dealing with an other-process actor. We
|
||||
// want to initialize OpenDatabaseOp/DeleteDatabaseOp here with the ID
|
||||
// (and later also Database) in that case, so Database::IsOwnedByProcess
|
||||
// can find Databases belonging to a particular content process when
|
||||
// QuotaClient::AbortOperationsForProcess is called which is currently used
|
||||
// to abort operations for content processes only.
|
||||
contentParentId = Some(ContentParentId(childID));
|
||||
}
|
||||
Maybe<ContentParentId> contentParentId = GetContentParentId();
|
||||
|
||||
auto actor = [&]() -> RefPtr<FactoryRequestOp> {
|
||||
if (aParams.type() == FactoryRequestParams::TOpenDatabaseRequestParams) {
|
||||
|
@ -9229,6 +9264,64 @@ bool Factory::DeallocPBackgroundIDBFactoryRequestParent(
|
|||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult Factory::RecvGetDatabases(
|
||||
const PersistenceType& aPersistenceType,
|
||||
const PrincipalInfo& aPrincipalInfo, GetDatabasesResolver&& aResolve) {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto ResolveGetDatabasesAndReturn = [&aResolve](const nsresult rv) {
|
||||
aResolve(rv);
|
||||
return IPC_OK();
|
||||
};
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(!QuotaClient::IsShuttingDownOnBackgroundThread()),
|
||||
ResolveGetDatabasesAndReturn);
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(IsValidPersistenceType(aPersistenceType)),
|
||||
QM_IPC_FAIL(this));
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(QuotaManager::IsPrincipalInfoValid(aPrincipalInfo)),
|
||||
QM_IPC_FAIL(this));
|
||||
|
||||
MOZ_ASSERT(aPrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo ||
|
||||
aPrincipalInfo.type() == PrincipalInfo::TContentPrincipalInfo);
|
||||
|
||||
PersistenceType persistenceType =
|
||||
IDBFactory::GetPersistenceType(aPrincipalInfo);
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(aPersistenceType == persistenceType), QM_IPC_FAIL(this));
|
||||
|
||||
Maybe<ContentParentId> contentParentId = GetContentParentId();
|
||||
|
||||
auto op = MakeRefPtr<GetDatabasesOp>(SafeRefPtrFromThis(), contentParentId,
|
||||
aPersistenceType, aPrincipalInfo,
|
||||
std::move(aResolve));
|
||||
|
||||
gFactoryOps->AppendElement(op);
|
||||
|
||||
// Balanced in CleanupMetadata() which is/must always called by SendResults().
|
||||
IncreaseBusyCount();
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(op));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
Maybe<ContentParentId> Factory::GetContentParentId() const {
|
||||
uint64_t childID = BackgroundParent::GetChildID(Manager());
|
||||
if (childID) {
|
||||
// If childID is not zero we are dealing with an other-process actor. We
|
||||
// want to initialize OpenDatabaseOp/DeleteDatabaseOp here with the ID
|
||||
// (and later also Database) in that case, so Database::IsOwnedByProcess
|
||||
// can find Databases belonging to a particular content process when
|
||||
// QuotaClient::AbortOperationsForProcess is called which is currently used
|
||||
// to abort operations for content processes only.
|
||||
return Some(ContentParentId(childID));
|
||||
}
|
||||
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* WaitForTransactionsHelper
|
||||
******************************************************************************/
|
||||
|
@ -16626,6 +16719,202 @@ nsresult DeleteDatabaseOp::VersionChangeOp::Run() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetDatabasesOp::DatabasesNotAvailable() {
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(mState == State::DatabaseWorkOpen);
|
||||
|
||||
mState = State::SendingResults;
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(mOwningEventTarget->Dispatch(this, NS_DISPATCH_NORMAL)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetDatabasesOp::DatabaseOpen() {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mState == State::DatabaseOpenPending);
|
||||
|
||||
nsresult rv = SendToIOThread();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetDatabasesOp::DoDatabaseWork() {
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(mState == State::DatabaseWorkOpen);
|
||||
|
||||
AUTO_PROFILER_LABEL("GetDatabasesOp::DoDatabaseWork", DOM);
|
||||
|
||||
if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
|
||||
!OperationMayProceed()) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
QuotaManager* const quotaManager = QuotaManager::Get();
|
||||
MOZ_ASSERT(quotaManager);
|
||||
|
||||
if (mPersistenceType != PERSISTENCE_TYPE_PERSISTENT) {
|
||||
QM_TRY(MOZ_TO_RESULT(
|
||||
quotaManager->EnsureTemporaryStorageIsInitializedInternal()));
|
||||
}
|
||||
|
||||
{
|
||||
QM_TRY_INSPECT(const bool& exists,
|
||||
quotaManager->DoesOriginDirectoryExist(mOriginMetadata));
|
||||
if (!exists) {
|
||||
return DatabasesNotAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
QM_TRY((["aManager, this]()
|
||||
-> mozilla::Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> {
|
||||
if (mPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||
QM_TRY_RETURN(
|
||||
quotaManager->EnsurePersistentOriginIsInitialized(mOriginMetadata));
|
||||
}
|
||||
|
||||
QM_TRY_RETURN(quotaManager->EnsureTemporaryOriginIsInitialized(
|
||||
mPersistenceType, mOriginMetadata));
|
||||
}()
|
||||
.map([](const auto& res) { return Ok{}; })));
|
||||
|
||||
{
|
||||
QM_TRY_INSPECT(const bool& exists,
|
||||
quotaManager->DoesClientDirectoryExist(
|
||||
ClientMetadata{mOriginMetadata, Client::IDB}));
|
||||
if (!exists) {
|
||||
return DatabasesNotAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
QM_TRY_INSPECT(
|
||||
const auto& clientDirectory,
|
||||
(["aManager, this]()
|
||||
-> mozilla::Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult> {
|
||||
if (mPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||
QM_TRY_RETURN(quotaManager->EnsurePersistentClientIsInitialized(
|
||||
ClientMetadata{mOriginMetadata, Client::IDB}));
|
||||
}
|
||||
|
||||
QM_TRY_RETURN(quotaManager->EnsureTemporaryClientIsInitialized(
|
||||
ClientMetadata{mOriginMetadata, Client::IDB}));
|
||||
}()
|
||||
.map([](const auto& res) { return res.first; })));
|
||||
|
||||
QM_TRY_INSPECT(
|
||||
(const auto& [subdirsToProcess, databaseFilenames]),
|
||||
QuotaClient::GetDatabaseFilenames(*clientDirectory,
|
||||
/* aCanceled */ Atomic<bool>{false}));
|
||||
|
||||
for (const auto& databaseFilename : databaseFilenames) {
|
||||
QM_TRY_INSPECT(
|
||||
const auto& databaseFile,
|
||||
CloneFileAndAppend(*clientDirectory, databaseFilename + kSQLiteSuffix));
|
||||
|
||||
nsString path;
|
||||
databaseFile->GetPath(path);
|
||||
|
||||
IndexedDatabaseManager* const idm = IndexedDatabaseManager::Get();
|
||||
MOZ_ASSERT(idm);
|
||||
|
||||
// If the database is already open then there will be a DatabaseFileManager
|
||||
// which can provide us with the database name and version without needing
|
||||
// to open the SQLite database. (Also, we are not allowed to open the
|
||||
// database on this thread if it's already open.)
|
||||
|
||||
SafeRefPtr<DatabaseFileManager> fileManager =
|
||||
idm->GetFileManagerByDatabaseFilePath(mPersistenceType,
|
||||
mOriginMetadata.mOrigin, path);
|
||||
|
||||
if (fileManager) {
|
||||
mDatabaseMetadataArray.AppendElement(
|
||||
DatabaseMetadata(nsString(fileManager->DatabaseName()),
|
||||
fileManager->DatabaseVersion(), mPersistenceType));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Since the database is not already open, it is safe and necessary for us
|
||||
// to open the database on this thread and retrieve its name and version.
|
||||
// We do not need to worry about racing a database open because database
|
||||
// opens can only be processed on this thread and we are performing the
|
||||
// steps below synchronously.
|
||||
|
||||
QM_TRY_INSPECT(
|
||||
const auto& fmDirectory,
|
||||
CloneFileAndAppend(*clientDirectory,
|
||||
databaseFilename + kFileManagerDirectoryNameSuffix));
|
||||
|
||||
QM_TRY_UNWRAP(
|
||||
const NotNull<nsCOMPtr<mozIStorageConnection>> connection,
|
||||
CreateStorageConnection(*databaseFile, *fmDirectory, VoidString(),
|
||||
mOriginMetadata.mOrigin, mDirectoryLockId,
|
||||
TelemetryIdForFile(databaseFile), Nothing{}));
|
||||
|
||||
{
|
||||
// Load version information.
|
||||
QM_TRY_INSPECT(const auto& stmt,
|
||||
CreateAndExecuteSingleStepStatement<
|
||||
SingleStepResult::ReturnNullIfNoResult>(
|
||||
*connection, "SELECT name, version FROM database"_ns));
|
||||
|
||||
QM_TRY(OkIf(stmt), NS_ERROR_FILE_CORRUPTED);
|
||||
|
||||
QM_TRY_INSPECT(
|
||||
const auto& databaseName,
|
||||
MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsString, stmt, GetString, 0));
|
||||
|
||||
QM_TRY_INSPECT(const int64_t& version,
|
||||
MOZ_TO_RESULT_INVOKE_MEMBER(stmt, GetInt64, 1));
|
||||
|
||||
mDatabaseMetadataArray.AppendElement(
|
||||
DatabaseMetadata(databaseName, version, mPersistenceType));
|
||||
}
|
||||
}
|
||||
|
||||
mState = State::SendingResults;
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(mOwningEventTarget->Dispatch(this, NS_DISPATCH_NORMAL)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetDatabasesOp::BeginVersionChange() {
|
||||
MOZ_CRASH("Not implemented because this should be unreachable.");
|
||||
}
|
||||
|
||||
bool GetDatabasesOp::AreActorsAlive() {
|
||||
MOZ_CRASH("Not implemented because this should be unreachable.");
|
||||
}
|
||||
|
||||
void GetDatabasesOp::SendBlockedNotification() {
|
||||
MOZ_CRASH("Not implemented because this should be unreachable.");
|
||||
}
|
||||
|
||||
nsresult GetDatabasesOp::DispatchToWorkThread() {
|
||||
MOZ_CRASH("Not implemented because this should be unreachable.");
|
||||
}
|
||||
|
||||
void GetDatabasesOp::SendResults() {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mState == State::SendingResults);
|
||||
|
||||
#ifdef DEBUG
|
||||
NoteActorDestroyed();
|
||||
#endif
|
||||
|
||||
mResolver(mDatabaseMetadataArray);
|
||||
|
||||
mDirectoryLock = nullptr;
|
||||
|
||||
CleanupMetadata();
|
||||
|
||||
FinishSendResults();
|
||||
}
|
||||
|
||||
TransactionDatabaseOperationBase::TransactionDatabaseOperationBase(
|
||||
SafeRefPtr<TransactionBase> aTransaction, const int64_t aRequestId)
|
||||
: DatabaseOperationBase(aTransaction->GetLoggingInfo()->Id(),
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/IDBFactoryBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/quota/PersistenceType.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/dom/quota/ResultExtensions.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
|
@ -53,30 +53,6 @@ using namespace mozilla::ipc;
|
|||
|
||||
namespace {
|
||||
|
||||
PersistenceType GetPersistenceType(const PrincipalInfo& aPrincipalInfo) {
|
||||
if (aPrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
// Chrome privilege always gets persistent storage.
|
||||
return PERSISTENCE_TYPE_PERSISTENT;
|
||||
}
|
||||
|
||||
if (aPrincipalInfo.type() == PrincipalInfo::TContentPrincipalInfo) {
|
||||
nsCString origin =
|
||||
aPrincipalInfo.get_ContentPrincipalInfo().originNoSuffix();
|
||||
|
||||
if (QuotaManager::IsOriginInternal(origin)) {
|
||||
// Internal origins always get persistent storage.
|
||||
return PERSISTENCE_TYPE_PERSISTENT;
|
||||
}
|
||||
|
||||
if (aPrincipalInfo.get_ContentPrincipalInfo().attrs().mPrivateBrowsingId >
|
||||
0) {
|
||||
return PERSISTENCE_TYPE_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
return PERSISTENCE_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
Telemetry::LABELS_IDB_CUSTOM_OPEN_WITH_OPTIONS_COUNT IdentifyPrincipalType(
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo) {
|
||||
switch (aPrincipalInfo.type()) {
|
||||
|
@ -403,6 +379,32 @@ bool IDBFactory::AllowedForPrincipal(nsIPrincipal* aPrincipal,
|
|||
return !aPrincipal->GetIsNullPrincipal();
|
||||
}
|
||||
|
||||
// static
|
||||
PersistenceType IDBFactory::GetPersistenceType(
|
||||
const PrincipalInfo& aPrincipalInfo) {
|
||||
if (aPrincipalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
// Chrome privilege always gets persistent storage.
|
||||
return PERSISTENCE_TYPE_PERSISTENT;
|
||||
}
|
||||
|
||||
if (aPrincipalInfo.type() == PrincipalInfo::TContentPrincipalInfo) {
|
||||
nsCString origin =
|
||||
aPrincipalInfo.get_ContentPrincipalInfo().originNoSuffix();
|
||||
|
||||
if (QuotaManager::IsOriginInternal(origin)) {
|
||||
// Internal origins always get persistent storage.
|
||||
return PERSISTENCE_TYPE_PERSISTENT;
|
||||
}
|
||||
|
||||
if (aPrincipalInfo.get_ContentPrincipalInfo().attrs().mPrivateBrowsingId >
|
||||
0) {
|
||||
return PERSISTENCE_TYPE_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
||||
return PERSISTENCE_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
void IDBFactory::UpdateActiveTransactionCount(int32_t aDelta) {
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(aDelta > 0 || (mActiveTransactionCount + aDelta) <
|
||||
|
@ -471,9 +473,64 @@ RefPtr<IDBOpenDBRequest> IDBFactory::DeleteDatabase(
|
|||
already_AddRefed<Promise> IDBFactory::Databases(JSContext* const aCx) {
|
||||
RefPtr<Promise> promise = Promise::CreateInfallible(GetOwnerGlobal());
|
||||
|
||||
Sequence<IDBDatabaseInfo> databaseInfos;
|
||||
// Nothing can be done here if we have previously failed to create a
|
||||
// background actor.
|
||||
if (mBackgroundActorFailed) {
|
||||
promise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
promise->MaybeResolve(databaseInfos);
|
||||
PersistenceType persistenceType = GetPersistenceType(*mPrincipalInfo);
|
||||
|
||||
QM_TRY(MOZ_TO_RESULT(EnsureBackgroundActor()), [&promise](const nsresult rv) {
|
||||
promise->MaybeReject(rv);
|
||||
return promise.forget();
|
||||
});
|
||||
|
||||
mBackgroundActor->SendGetDatabases(persistenceType, *mPrincipalInfo)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise](const PBackgroundIDBFactoryChild::GetDatabasesPromise::
|
||||
ResolveOrRejectValue& aValue) {
|
||||
if (aValue.IsReject()) {
|
||||
promise->MaybeReject(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
const GetDatabasesResponse& response = aValue.ResolveValue();
|
||||
|
||||
switch (response.type()) {
|
||||
case GetDatabasesResponse::Tnsresult:
|
||||
promise->MaybeReject(response.get_nsresult());
|
||||
|
||||
break;
|
||||
|
||||
case GetDatabasesResponse::TArrayOfDatabaseMetadata: {
|
||||
const auto& array = response.get_ArrayOfDatabaseMetadata();
|
||||
|
||||
Sequence<IDBDatabaseInfo> databaseInfos;
|
||||
|
||||
for (const auto& databaseMetadata : array) {
|
||||
IDBDatabaseInfo databaseInfo;
|
||||
|
||||
databaseInfo.mName.Construct(databaseMetadata.name());
|
||||
databaseInfo.mVersion.Construct(databaseMetadata.version());
|
||||
|
||||
if (!databaseInfos.AppendElement(std::move(databaseInfo),
|
||||
fallible)) {
|
||||
promise->MaybeRejectWithTypeError("Out of memory");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
promise->MaybeResolve(databaseInfos);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unknown response type!");
|
||||
}
|
||||
});
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/quota/PersistenceType.h"
|
||||
#include "mozilla/GlobalTeardownObserver.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -97,6 +98,9 @@ class IDBFactory final : public GlobalTeardownObserver, public nsWrapperCache {
|
|||
static bool AllowedForPrincipal(nsIPrincipal* aPrincipal,
|
||||
bool* aIsSystemPrincipal = nullptr);
|
||||
|
||||
static quota::PersistenceType GetPersistenceType(
|
||||
const PrincipalInfo& aPrincipalInfo);
|
||||
|
||||
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(IDBFactory); }
|
||||
|
||||
nsISerialEventTarget* EventTarget() const {
|
||||
|
|
|
@ -40,6 +40,12 @@ union FactoryRequestParams
|
|||
DeleteDatabaseRequestParams;
|
||||
};
|
||||
|
||||
union GetDatabasesResponse
|
||||
{
|
||||
nsresult;
|
||||
DatabaseMetadata[];
|
||||
};
|
||||
|
||||
[ChildImpl="indexedDB::BackgroundFactoryChild", ParentImpl=virtual]
|
||||
sync protocol PBackgroundIDBFactory
|
||||
{
|
||||
|
@ -53,6 +59,10 @@ parent:
|
|||
|
||||
async PBackgroundIDBFactoryRequest(FactoryRequestParams params);
|
||||
|
||||
async GetDatabases(PersistenceType persistenceType,
|
||||
PrincipalInfo principalInfo)
|
||||
returns(GetDatabasesResponse response);
|
||||
|
||||
child:
|
||||
async __delete__();
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
[database-names-by-origin.html]
|
||||
expected: OK
|
||||
[open database names don't leak to cross-origin iframe]
|
||||
expected: FAIL
|
||||
|
||||
[open database names don't leak to cross-origin window]
|
||||
expected: FAIL
|
||||
|
||||
[closed database names don't leak to cross-origin iframe]
|
||||
expected: FAIL
|
||||
|
||||
[closed database names don't leak to cross-origin window]
|
||||
expected: FAIL
|
|
@ -1,16 +1,6 @@
|
|||
[get-databases.any.html]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [OK, TIMEOUT]
|
||||
[Enumerate multiple databases.]
|
||||
expected: FAIL
|
||||
|
||||
[Enumerate one database.]
|
||||
expected: FAIL
|
||||
|
||||
[Make sure an empty list is returned for the case of no databases.]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [FAIL, TIMEOUT]
|
||||
PASS
|
||||
|
||||
[Ensure that databases() doesn't pick up changes that haven't commited.]
|
||||
expected:
|
||||
|
@ -21,16 +11,6 @@
|
|||
[get-databases.any.worker.html]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [OK, TIMEOUT]
|
||||
[Enumerate multiple databases.]
|
||||
expected: FAIL
|
||||
|
||||
[Enumerate one database.]
|
||||
expected: FAIL
|
||||
|
||||
[Make sure an empty list is returned for the case of no databases.]
|
||||
expected:
|
||||
if (processor == "x86") and not debug: [FAIL, TIMEOUT]
|
||||
PASS
|
||||
|
||||
[Ensure that databases() doesn't pick up changes that haven't commited.]
|
||||
expected:
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
[idbfactory-origin-isolation.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [TIMEOUT, OK]
|
||||
[Test to make sure that origins have separate locking schemes]
|
||||
expected: FAIL
|
||||
|
|
Загрузка…
Ссылка в новой задаче