Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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