diff options
Diffstat (limited to 'dom/fs/parent/FileSystemManagerParentFactory.cpp')
-rw-r--r-- | dom/fs/parent/FileSystemManagerParentFactory.cpp | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/dom/fs/parent/FileSystemManagerParentFactory.cpp b/dom/fs/parent/FileSystemManagerParentFactory.cpp new file mode 100644 index 0000000000..a7a4b13664 --- /dev/null +++ b/dom/fs/parent/FileSystemManagerParentFactory.cpp @@ -0,0 +1,114 @@ +/* -*- 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 "FileSystemManagerParentFactory.h" + +#include "mozilla/OriginAttributes.h" +#include "mozilla/StaticPrefs_dom.h" +#include "mozilla/dom/FileSystemDataManager.h" +#include "mozilla/dom/FileSystemLog.h" +#include "mozilla/dom/FileSystemManagerParent.h" +#include "mozilla/dom/FileSystemTypes.h" +#include "mozilla/dom/quota/QuotaCommon.h" +#include "mozilla/dom/quota/QuotaManager.h" +#include "mozilla/dom/quota/ResultExtensions.h" +#include "mozilla/ipc/Endpoint.h" +#include "nsIScriptObjectPrincipal.h" +#include "nsString.h" + +namespace mozilla::dom { +mozilla::ipc::IPCResult CreateFileSystemManagerParent( + const mozilla::ipc::PrincipalInfo& aPrincipalInfo, + mozilla::ipc::Endpoint<PFileSystemManagerParent>&& aParentEndpoint, + std::function<void(const nsresult&)>&& aResolver) { + using CreateActorPromise = + MozPromise<RefPtr<FileSystemManagerParent>, nsresult, true>; + + QM_TRY(OkIf(StaticPrefs::dom_fs_enabled()), IPC_OK(), + [aResolver](const auto&) { aResolver(NS_ERROR_DOM_NOT_ALLOWED_ERR); }); + + QM_TRY(OkIf(aParentEndpoint.IsValid()), IPC_OK(), + [aResolver](const auto&) { aResolver(NS_ERROR_INVALID_ARG); }); + + // This blocks Null and Expanded principals + QM_TRY(OkIf(quota::QuotaManager::IsPrincipalInfoValid(aPrincipalInfo)), + IPC_OK(), + [aResolver](const auto&) { aResolver(NS_ERROR_DOM_SECURITY_ERR); }); + + QM_TRY(quota::QuotaManager::EnsureCreated(), IPC_OK(), + [aResolver](const auto rv) { aResolver(rv); }); + + auto* const quotaManager = quota::QuotaManager::Get(); + MOZ_ASSERT(quotaManager); + + QM_TRY_UNWRAP(auto principalMetadata, + quotaManager->GetInfoFromValidatedPrincipalInfo(aPrincipalInfo), + IPC_OK(), [aResolver](const auto rv) { aResolver(rv); }); + + quota::OriginMetadata originMetadata(std::move(principalMetadata), + quota::PERSISTENCE_TYPE_DEFAULT); + + // Block use for now in PrivateBrowsing + QM_TRY(OkIf(!OriginAttributes::IsPrivateBrowsing(originMetadata.mOrigin)), + IPC_OK(), + [aResolver](const auto&) { aResolver(NS_ERROR_DOM_NOT_ALLOWED_ERR); }); + + LOG(("CreateFileSystemManagerParent, origin: %s", + originMetadata.mOrigin.get())); + + // This creates the file system data manager, which has to be done on + // PBackground + fs::data::FileSystemDataManager::GetOrCreateFileSystemDataManager( + originMetadata) + ->Then( + GetCurrentSerialEventTarget(), __func__, + [origin = originMetadata.mOrigin, + parentEndpoint = std::move(aParentEndpoint), + aResolver](const fs::Registered<fs::data::FileSystemDataManager>& + dataManager) mutable { + QM_TRY_UNWRAP( + fs::EntryId rootId, fs::data::GetRootHandle(origin), QM_VOID, + [aResolver](const auto& aRv) { aResolver(ToNSResult(aRv)); }); + + InvokeAsync( + dataManager->MutableIOTaskQueuePtr(), __func__, + [dataManager = + RefPtr<fs::data::FileSystemDataManager>(dataManager), + rootId, parentEndpoint = std::move(parentEndpoint)]() mutable { + RefPtr<FileSystemManagerParent> parent = + new FileSystemManagerParent(std::move(dataManager), + rootId); + + LOG(("Binding parent endpoint")); + if (!parentEndpoint.Bind(parent)) { + return CreateActorPromise::CreateAndReject(NS_ERROR_FAILURE, + __func__); + } + + return CreateActorPromise::CreateAndResolve(std::move(parent), + __func__); + }) + ->Then(GetCurrentSerialEventTarget(), __func__, + [dataManager = dataManager, aResolver]( + CreateActorPromise::ResolveOrRejectValue&& aValue) { + if (aValue.IsReject()) { + aResolver(aValue.RejectValue()); + } else { + RefPtr<FileSystemManagerParent> parent = + std::move(aValue.ResolveValue()); + + dataManager->RegisterActor(WrapNotNull(parent)); + + aResolver(NS_OK); + } + }); + }, + [aResolver](nsresult aRejectValue) { aResolver(aRejectValue); }); + + return IPC_OK(); +} + +} // namespace mozilla::dom |