Bug 1534712 - Port FileCreatorHelper to PBackground, r=smaug

FileCreatorHelper creates a FileBlobImpl on the main-thread and, because of
this, we end up executing I/O operations on that thread, slowing down other
components.  With this patch, FileCreatorHelper logic is moved to PBackground.

That the 'type' getter is still called on the main-thread because FileBlobImpl
uses nsIMIMEService which is a non thread-safe component.

Differential Revision: https://phabricator.services.mozilla.com/D27641

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrea Marchesini 2019-04-26 17:53:07 +00:00
Родитель 72d6086fa4
Коммит 35bde55efd
32 изменённых файлов: 503 добавлений и 464 удалений

Просмотреть файл

@ -28,14 +28,14 @@ void BaseBlobImpl::SetDOMPath(const nsAString& aPath) {
void BaseBlobImpl::GetMozFullPath(nsAString& aFileName,
SystemCallerGuarantee /* unused */,
ErrorResult& aRv) const {
ErrorResult& aRv) {
MOZ_ASSERT(mIsFile, "Should only be called on files");
GetMozFullPathInternal(aFileName, aRv);
}
void BaseBlobImpl::GetMozFullPathInternal(nsAString& aFileName,
ErrorResult& aRv) const {
ErrorResult& aRv) {
if (!mIsFile) {
aRv.Throw(NS_ERROR_FAILURE);
return;

Просмотреть файл

@ -86,10 +86,10 @@ class BaseBlobImpl : public BlobImpl {
virtual void GetMozFullPath(nsAString& aName,
SystemCallerGuarantee /* unused */,
ErrorResult& aRv) const override;
ErrorResult& aRv) override;
virtual void GetMozFullPathInternal(nsAString& aFileName,
ErrorResult& aRv) const override;
ErrorResult& aRv) override;
virtual uint64_t GetSize(ErrorResult& aRv) override { return mLength; }

Просмотреть файл

@ -45,10 +45,10 @@ class BlobImpl : public nsISupports {
virtual void GetMozFullPath(nsAString& aName,
SystemCallerGuarantee /* unused */,
ErrorResult& aRv) const = 0;
ErrorResult& aRv) = 0;
virtual void GetMozFullPathInternal(nsAString& aFileName,
ErrorResult& aRv) const = 0;
ErrorResult& aRv) = 0;
virtual uint64_t GetSize(ErrorResult& aRv) = 0;

Просмотреть файл

@ -100,13 +100,11 @@ int64_t File::GetLastModified(ErrorResult& aRv) {
}
void File::GetMozFullPath(nsAString& aFilename,
SystemCallerGuarantee aGuarantee,
ErrorResult& aRv) const {
SystemCallerGuarantee aGuarantee, ErrorResult& aRv) {
mImpl->GetMozFullPath(aFilename, aGuarantee, aRv);
}
void File::GetMozFullPathInternal(nsAString& aFileName,
ErrorResult& aRv) const {
void File::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv) {
mImpl->GetMozFullPathInternal(aFileName, aRv);
}

Просмотреть файл

@ -88,9 +88,9 @@ class File final : public Blob {
void GetRelativePath(nsAString& aPath) const;
void GetMozFullPath(nsAString& aFilename, SystemCallerGuarantee aGuarantee,
ErrorResult& aRv) const;
ErrorResult& aRv);
void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv) const;
void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv);
protected:
virtual bool HasFileInterface() const override { return true; }

Просмотреть файл

@ -22,12 +22,13 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile)
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), EmptyString(),
EmptyString(), UINT64_MAX, INT64_MAX),
mFile(aFile),
mWholeFile(true),
mFileId(-1) {
mFileId(-1),
mWholeFile(true) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
// Lazily get the content type and size
mContentType.SetIsVoid(true);
mMozFullPath.SetIsVoid(true);
mFile->GetLeafName(mName);
}
@ -37,10 +38,11 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName,
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aName, aContentType,
aLength, UINT64_MAX),
mFile(aFile),
mWholeFile(true),
mFileId(-1) {
mFileId(-1),
mWholeFile(true) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
mMozFullPath.SetIsVoid(true);
}
FileBlobImpl::FileBlobImpl(const nsAString& aName,
@ -49,10 +51,11 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName,
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aName, aContentType,
aLength, aLastModificationDate),
mFile(aFile),
mWholeFile(true),
mFileId(-1) {
mFileId(-1),
mWholeFile(true) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
mMozFullPath.SetIsVoid(true);
}
FileBlobImpl::FileBlobImpl(nsIFile* aFile, const nsAString& aName,
@ -60,14 +63,16 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile, const nsAString& aName,
const nsAString& aBlobImplType)
: BaseBlobImpl(aBlobImplType, aName, aContentType, UINT64_MAX, INT64_MAX),
mFile(aFile),
mWholeFile(true),
mFileId(-1) {
mFileId(-1),
mWholeFile(true) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
if (aContentType.IsEmpty()) {
// Lazily get the content type and size
mContentType.SetIsVoid(true);
}
mMozFullPath.SetIsVoid(true);
}
FileBlobImpl::FileBlobImpl(const FileBlobImpl* aOther, uint64_t aStart,
@ -75,24 +80,37 @@ FileBlobImpl::FileBlobImpl(const FileBlobImpl* aOther, uint64_t aStart,
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aContentType,
aOther->mStart + aStart, aLength),
mFile(aOther->mFile),
mWholeFile(false),
mFileId(-1) {
mFileId(-1),
mWholeFile(false) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
mImmutable = aOther->mImmutable;
mMozFullPath = aOther->mMozFullPath;
}
already_AddRefed<BlobImpl> FileBlobImpl::CreateSlice(
uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
ErrorResult& aRv) {
RefPtr<BlobImpl> impl = new FileBlobImpl(this, aStart, aLength, aContentType);
RefPtr<FileBlobImpl> impl =
new FileBlobImpl(this, aStart, aLength, aContentType);
return impl.forget();
}
void FileBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
ErrorResult& aRv) const {
ErrorResult& aRv) {
MOZ_ASSERT(mIsFile, "Should only be called on files");
if (!mMozFullPath.IsVoid()) {
aFilename = mMozFullPath;
return;
}
aRv = mFile->GetPath(aFilename);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
mMozFullPath = aFilename;
}
uint64_t FileBlobImpl::GetSize(ErrorResult& aRv) {
@ -205,10 +223,6 @@ int64_t FileBlobImpl::GetLastModified(ErrorResult& aRv) {
return mLastModificationDate;
}
void FileBlobImpl::SetLastModified(int64_t aLastModified) {
MOZ_CRASH("SetLastModified of a real file is not allowed!");
}
const uint32_t sFileStreamFlags =
nsIFileInputStream::CLOSE_ON_EOF | nsIFileInputStream::REOPEN_ON_REWIND |
nsIFileInputStream::DEFER_OPEN | nsIFileInputStream::SHARE_DELETE;

Просмотреть файл

@ -37,9 +37,8 @@ class FileBlobImpl : public BaseBlobImpl {
virtual uint64_t GetSize(ErrorResult& aRv) override;
virtual void GetType(nsAString& aType) override;
virtual int64_t GetLastModified(ErrorResult& aRv) override;
virtual void SetLastModified(int64_t aLastModified) override;
virtual void GetMozFullPathInternal(nsAString& aFullPath,
ErrorResult& aRv) const override;
ErrorResult& aRv) override;
virtual void CreateInputStream(nsIInputStream** aInputStream,
ErrorResult& aRv) override;
@ -57,6 +56,10 @@ class FileBlobImpl : public BaseBlobImpl {
void SetFileId(int64_t aFileId) { mFileId = aFileId; }
void SetEmptySize() { mLength = 0; }
void SetMozFullPath(const nsAString& aPath) { mMozFullPath = aPath; }
protected:
virtual ~FileBlobImpl() = default;
@ -70,8 +73,9 @@ class FileBlobImpl : public BaseBlobImpl {
ErrorResult& aRv) override;
nsCOMPtr<nsIFile> mFile;
bool mWholeFile;
nsString mMozFullPath;
int64_t mFileId;
bool mWholeFile;
};
} // namespace dom

Просмотреть файл

@ -7,13 +7,16 @@
#include "FileCreatorHelper.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/FileBinding.h"
#include "mozilla/dom/ipc/FileCreatorChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/StaticPrefs.h"
#include "nsContentUtils.h"
#include "nsPIDOMWindow.h"
#include "nsProxyRelease.h"
#include "nsIFile.h"
// Undefine the macro of CreateFile to avoid FileCreatorHelper#CreateFile being
@ -36,167 +39,32 @@ already_AddRefed<Promise> FileCreatorHelper::CreateFile(
return nullptr;
}
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobalObject);
// Parent process
if (XRE_IsParentProcess()) {
RefPtr<File> file =
CreateFileInternal(window, aFile, aBag, aIsFromNsIFile, aRv);
if (aRv.Failed()) {
return nullptr;
}
promise->MaybeResolve(file);
return promise.forget();
}
// Content process.
ContentChild* cc = ContentChild::GetSingleton();
if (!cc) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
if (!cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE) &&
!Preferences::GetBool("dom.file.createInChild", false)) {
// If this pref is not set and the request is received by the parent
// process, this child is killed for security reason.
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return promise.forget();
}
RefPtr<FileCreatorHelper> helper = new FileCreatorHelper(promise, window);
// The request is sent to the parent process and it's kept alive by
// ContentChild.
helper->SendRequest(aFile, aBag, aIsFromNsIFile, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
return promise.forget();
}
/* static */
already_AddRefed<File> FileCreatorHelper::CreateFileInternal(
nsPIDOMWindowInner* aWindow, nsIFile* aFile,
const ChromeFilePropertyBag& aBag, bool aIsFromNsIFile, ErrorResult& aRv) {
bool lastModifiedPassed = false;
int64_t lastModified = 0;
if (aBag.mLastModified.WasPassed()) {
lastModifiedPassed = true;
lastModified = aBag.mLastModified.Value();
}
RefPtr<BlobImpl> blobImpl;
aRv = CreateBlobImpl(aFile, aBag.mType, aBag.mName, lastModifiedPassed,
lastModified, aBag.mExistenceCheck, aIsFromNsIFile,
getter_AddRefs(blobImpl));
if (aRv.Failed()) {
return nullptr;
}
RefPtr<File> file = File::Create(aWindow, blobImpl);
return file.forget();
}
FileCreatorHelper::FileCreatorHelper(Promise* aPromise,
nsPIDOMWindowInner* aWindow)
: mPromise(aPromise), mWindow(aWindow) {
MOZ_ASSERT(aPromise);
}
FileCreatorHelper::~FileCreatorHelper() {}
void FileCreatorHelper::SendRequest(nsIFile* aFile,
const ChromeFilePropertyBag& aBag,
bool aIsFromNsIFile, ErrorResult& aRv) {
MOZ_ASSERT(aFile);
ContentChild* cc = ContentChild::GetSingleton();
if (NS_WARN_IF(!cc)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsID uuid;
aRv = nsContentUtils::GenerateUUIDInPlace(uuid);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
nsAutoString path;
aRv = aFile->GetPath(path);
if (NS_WARN_IF(aRv.Failed())) {
return;
return nullptr;
}
cc->FileCreationRequest(uuid, this, path, aBag.mType, aBag.mName,
aBag.mLastModified, aBag.mExistenceCheck,
aIsFromNsIFile);
}
void FileCreatorHelper::ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv) {
if (NS_FAILED(aRv)) {
mPromise->MaybeReject(aRv);
return;
// Register this component to PBackground.
mozilla::ipc::PBackgroundChild* actorChild =
mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!actorChild)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
RefPtr<File> file = File::Create(mWindow, aBlobImpl);
mPromise->MaybeResolve(file);
}
/* static */
nsresult FileCreatorHelper::CreateBlobImplForIPC(
const nsAString& aPath, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl) {
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(aPath, true, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
Maybe<int64_t> lastModified;
if (aBag.mLastModified.WasPassed()) {
lastModified.emplace(aBag.mLastModified.Value());
}
return CreateBlobImpl(file, aType, aName, aLastModifiedPassed, aLastModified,
aExistenceCheck, aIsFromNsIFile, aBlobImpl);
}
mozilla::ipc::PFileCreatorChild* actor =
actorChild->SendPFileCreatorConstructor(
path, aBag.mType, aBag.mName, lastModified, aBag.mExistenceCheck,
aIsFromNsIFile);
/* static */
nsresult FileCreatorHelper::CreateBlobImpl(
nsIFile* aFile, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl) {
if (!aExistenceCheck) {
RefPtr<FileBlobImpl> impl = new FileBlobImpl(aFile);
if (!aName.IsEmpty()) {
impl->SetName(aName);
}
if (!aType.IsEmpty()) {
impl->SetType(aType);
}
if (aLastModifiedPassed) {
impl->SetLastModified(aLastModified);
}
impl.forget(aBlobImpl);
return NS_OK;
}
RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
nsresult rv = impl->InitializeChromeFile(
aFile, aType, aName, aLastModifiedPassed, aLastModified, aIsFromNsIFile);
if (NS_FAILED(rv)) {
return rv;
}
MOZ_ASSERT(impl->IsFile());
impl.forget(aBlobImpl);
return NS_OK;
static_cast<FileCreatorChild*>(actor)->SetPromise(promise);
return promise.forget();
}
} // namespace dom

Просмотреть файл

@ -20,52 +20,20 @@
class nsIFile;
class nsIGlobalObject;
class nsPIDOMWindowInner;
namespace mozilla {
namespace dom {
struct ChromeFilePropertyBag;
class Promise;
class File;
class FileCreatorHelper final {
public:
NS_INLINE_DECL_REFCOUNTING(FileCreatorHelper);
static already_AddRefed<Promise> CreateFile(nsIGlobalObject* aGlobalObject,
nsIFile* aFile,
const ChromeFilePropertyBag& aBag,
bool aIsFromNsIFile,
ErrorResult& aRv);
void ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv);
// For IPC only
static nsresult CreateBlobImplForIPC(
const nsAString& aPath, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl);
private:
static already_AddRefed<File> CreateFileInternal(
nsPIDOMWindowInner* aWindow, nsIFile* aFile,
const ChromeFilePropertyBag& aBag, bool aIsFromNsIFile, ErrorResult& aRv);
static nsresult CreateBlobImpl(nsIFile* aFile, const nsAString& aType,
const nsAString& aName,
bool aLastModifiedPassed,
int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl);
FileCreatorHelper(Promise* aPromise, nsPIDOMWindowInner* aWindow);
~FileCreatorHelper();
void SendRequest(nsIFile* aFile, const ChromeFilePropertyBag& aBag,
bool aIsFromNsIFile, ErrorResult& aRv);
RefPtr<Promise> mPromise;
nsCOMPtr<nsPIDOMWindowInner> mWindow;
};
} // namespace dom

Просмотреть файл

@ -274,22 +274,6 @@ void MultipartBlobImpl::SetLengthAndModifiedDate(ErrorResult& aRv) {
}
}
void MultipartBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
ErrorResult& aRv) const {
if (!mIsFromNsIFile || mBlobImpls.Length() == 0) {
BaseBlobImpl::GetMozFullPathInternal(aFilename, aRv);
return;
}
BlobImpl* blobImpl = mBlobImpls.ElementAt(0).get();
if (!blobImpl) {
BaseBlobImpl::GetMozFullPathInternal(aFilename, aRv);
return;
}
blobImpl->GetMozFullPathInternal(aFilename, aRv);
}
nsresult MultipartBlobImpl::SetMutable(bool aMutable) {
nsresult rv;
@ -317,82 +301,6 @@ nsresult MultipartBlobImpl::SetMutable(bool aMutable) {
return NS_OK;
}
nsresult MultipartBlobImpl::InitializeChromeFile(
nsIFile* aFile, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aIsFromNsIFile) {
MOZ_ASSERT(!mImmutable, "Something went wrong ...");
if (mImmutable) {
return NS_ERROR_UNEXPECTED;
}
mName = aName;
mContentType = aType;
mIsFromNsIFile = aIsFromNsIFile;
bool exists;
nsresult rv = aFile->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!exists) {
return NS_ERROR_FILE_NOT_FOUND;
}
bool isDir;
rv = aFile->IsDirectory(&isDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDir) {
return NS_ERROR_FILE_IS_DIRECTORY;
}
if (mName.IsEmpty()) {
aFile->GetLeafName(mName);
}
RefPtr<File> blob = File::CreateFromFile(nullptr, aFile);
// Pre-cache size.
ErrorResult error;
blob->GetSize(error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
// Pre-cache modified date.
blob->GetLastModified(error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
// XXXkhuey this is terrible
if (mContentType.IsEmpty()) {
blob->GetType(mContentType);
}
BlobSet blobSet;
rv = blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mBlobImpls = blobSet.GetBlobImpls();
SetLengthAndModifiedDate(error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
if (aLastModifiedPassed) {
SetLastModified(aLastModified);
}
return NS_OK;
}
bool MultipartBlobImpl::MayBeClonedToOtherThreads() const {
for (uint32_t i = 0; i < mBlobImpls.Length(); ++i) {
if (!mBlobImpls[i]->MayBeClonedToOtherThreads()) {

Просмотреть файл

@ -32,14 +32,12 @@ class MultipartBlobImpl final : public BaseBlobImpl {
// Create as a file to be later initialized
explicit MultipartBlobImpl(const nsAString& aName)
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), aName,
EmptyString(), UINT64_MAX),
mIsFromNsIFile(false) {}
EmptyString(), UINT64_MAX) {}
// Create as a blob to be later initialized
MultipartBlobImpl()
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), EmptyString(),
UINT64_MAX),
mIsFromNsIFile(false) {}
UINT64_MAX) {}
void InitializeBlob(ErrorResult& aRv);
@ -47,11 +45,6 @@ class MultipartBlobImpl final : public BaseBlobImpl {
const nsAString& aContentType, bool aNativeEOL,
ErrorResult& aRv);
nsresult InitializeChromeFile(nsIFile* aData, const nsAString& aType,
const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified,
bool aIsFromNsIFile);
virtual already_AddRefed<BlobImpl> CreateSlice(uint64_t aStart,
uint64_t aLength,
const nsAString& aContentType,
@ -66,9 +59,6 @@ class MultipartBlobImpl final : public BaseBlobImpl {
return mBlobImpls.Length() ? &mBlobImpls : nullptr;
}
virtual void GetMozFullPathInternal(nsAString& aFullPath,
ErrorResult& aRv) const override;
virtual nsresult SetMutable(bool aMutable) override;
void SetName(const nsAString& aName) { mName = aName; }
@ -86,22 +76,19 @@ class MultipartBlobImpl final : public BaseBlobImpl {
const nsAString& aName, const nsAString& aContentType)
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), aName,
aContentType, UINT64_MAX),
mBlobImpls(std::move(aBlobImpls)),
mIsFromNsIFile(false) {}
mBlobImpls(std::move(aBlobImpls)) {}
MultipartBlobImpl(nsTArray<RefPtr<BlobImpl>>&& aBlobImpls,
const nsAString& aContentType)
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), aContentType,
UINT64_MAX),
mBlobImpls(std::move(aBlobImpls)),
mIsFromNsIFile(false) {}
mBlobImpls(std::move(aBlobImpls)) {}
virtual ~MultipartBlobImpl() {}
void SetLengthAndModifiedDate(ErrorResult& aRv);
nsTArray<RefPtr<BlobImpl>> mBlobImpls;
bool mIsFromNsIFile;
};
} // namespace dom

Просмотреть файл

@ -46,8 +46,7 @@ class StreamBlobImpl final : public BaseBlobImpl, public nsIMemoryReporter {
void SetFullPath(const nsAString& aFullPath) { mFullPath = aFullPath; }
void GetMozFullPathInternal(nsAString& aFullPath,
ErrorResult& aRv) const override {
void GetMozFullPathInternal(nsAString& aFullPath, ErrorResult& aRv) override {
aFullPath = mFullPath;
}

Просмотреть файл

@ -0,0 +1,55 @@
/* -*- 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 "FileCreatorChild.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/IPCBlobUtils.h"
namespace mozilla {
namespace dom {
FileCreatorChild::FileCreatorChild() = default;
FileCreatorChild::~FileCreatorChild() { MOZ_ASSERT(!mPromise); }
void FileCreatorChild::SetPromise(Promise* aPromise) {
MOZ_ASSERT(aPromise);
MOZ_ASSERT(!mPromise);
mPromise = aPromise;
}
mozilla::ipc::IPCResult FileCreatorChild::Recv__delete__(
const FileCreationResult& aResult) {
MOZ_ASSERT(mPromise);
RefPtr<Promise> promise;
promise.swap(mPromise);
if (aResult.type() == FileCreationResult::TFileCreationErrorResult) {
promise->MaybeReject(aResult.get_FileCreationErrorResult().errorCode());
return IPC_OK();
}
MOZ_ASSERT(aResult.type() == FileCreationResult::TFileCreationSuccessResult);
RefPtr<dom::BlobImpl> impl = dom::IPCBlobUtils::Deserialize(
aResult.get_FileCreationSuccessResult().blob());
RefPtr<File> file = File::Create(promise->GetParentObject(), impl);
promise->MaybeResolve(file);
return IPC_OK();
}
void FileCreatorChild::ActorDestroy(ActorDestroyReason aWhy) {
if (mPromise) {
mPromise->MaybeReject(NS_ERROR_FAILURE);
mPromise = nullptr;
}
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,36 @@
/* -*- 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/. */
#ifndef mozilla_dom_ipc_FileCreatorChild_h
#define mozilla_dom_ipc_FileCreatorChild_h
#include "mozilla/ipc/PFileCreatorChild.h"
namespace mozilla {
namespace dom {
class FileCreatorChild final : public mozilla::ipc::PFileCreatorChild {
friend class mozilla::ipc::PFileCreatorChild;
public:
FileCreatorChild();
~FileCreatorChild();
void SetPromise(Promise* aPromise);
private:
mozilla::ipc::IPCResult Recv__delete__(
const FileCreationResult& aResult) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
RefPtr<Promise> mPromise;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_FileCreatorChild_h

Просмотреть файл

@ -0,0 +1,136 @@
/* -*- 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 "FileCreatorParent.h"
#include "mozilla/dom/FileBlobImpl.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/MultipartBlobImpl.h"
namespace mozilla {
namespace dom {
FileCreatorParent::FileCreatorParent()
: mBackgroundEventTarget(GetCurrentThreadEventTarget()), mIPCActive(true) {}
FileCreatorParent::~FileCreatorParent() = default;
mozilla::ipc::IPCResult FileCreatorParent::CreateAndShareFile(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
RefPtr<dom::BlobImpl> blobImpl;
nsresult rv =
CreateBlobImpl(aFullPath, aType, aName, aLastModified.isSome(),
aLastModified.isSome() ? aLastModified.value() : 0,
aExistenceCheck, aIsFromNsIFile, getter_AddRefs(blobImpl));
if (NS_WARN_IF(NS_FAILED(rv))) {
Unused << Send__delete__(this, FileCreationErrorResult(rv));
return IPC_OK();
}
MOZ_ASSERT(blobImpl);
// FileBlobImpl is unable to return the correct type on this thread because
// nsIMIMEService is not thread-safe. We must exec the 'type' getter on
// main-thread before send the blob to the child actor.
RefPtr<FileCreatorParent> self = this;
NS_DispatchToMainThread(NS_NewRunnableFunction(
"FileCreatorParent::CreateAndShareFile", [self, blobImpl]() {
nsAutoString type;
blobImpl->GetType(type);
self->mBackgroundEventTarget->Dispatch(NS_NewRunnableFunction(
"FileCreatorParent::CreateAndShareFile return", [self, blobImpl]() {
if (self->mIPCActive) {
IPCBlob ipcBlob;
nsresult rv = dom::IPCBlobUtils::Serialize(
blobImpl, self->Manager(), ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
Unused << Send__delete__(self, FileCreationErrorResult(rv));
return;
}
Unused << Send__delete__(self,
FileCreationSuccessResult(ipcBlob));
}
}));
}));
return IPC_OK();
}
void FileCreatorParent::ActorDestroy(ActorDestroyReason aWhy) {
mIPCActive = false;
}
/* static */
nsresult FileCreatorParent::CreateBlobImpl(
const nsAString& aPath, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl) {
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(aPath, true, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (aExistenceCheck) {
bool exists;
nsresult rv = file->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!exists) {
return NS_ERROR_FILE_NOT_FOUND;
}
bool isDir;
rv = file->IsDirectory(&isDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDir) {
return NS_ERROR_FILE_IS_DIRECTORY;
}
}
RefPtr<FileBlobImpl> impl = new FileBlobImpl(file);
// If the file doesn't exist, we cannot have its path, its size and so on.
// Let's set them now.
if (!aExistenceCheck) {
impl->SetMozFullPath(aPath);
impl->SetLastModified(0);
impl->SetEmptySize();
}
if (!aName.IsEmpty()) {
impl->SetName(aName);
}
if (!aType.IsEmpty()) {
impl->SetType(aType);
}
if (aLastModifiedPassed) {
impl->SetLastModified(aLastModified);
}
if (!aIsFromNsIFile) {
impl->SetMozFullPath(EmptyString());
}
impl.forget(aBlobImpl);
return NS_OK;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,47 @@
/* -*- 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/. */
#ifndef mozilla_dom_ipc_FileCreatorParent_h
#define mozilla_dom_ipc_FileCreatorParent_h
#include "mozilla/ipc/PFileCreatorParent.h"
class nsIFile;
namespace mozilla {
namespace dom {
class BlobImpl;
class FileCreatorParent final : public mozilla::ipc::PFileCreatorParent {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileCreatorParent)
FileCreatorParent();
mozilla::ipc::IPCResult CreateAndShareFile(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile);
private:
~FileCreatorParent();
void ActorDestroy(ActorDestroyReason aWhy) override;
nsresult CreateBlobImpl(const nsAString& aPath, const nsAString& aType,
const nsAString& aName, bool aLastModifiedPassed,
int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl);
nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
bool mIPCActive;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_FileCreatorParent_h

Просмотреть файл

@ -0,0 +1,41 @@
/* 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 protocol PBackground;
include protocol PChildToParentStream;
include protocol PFileDescriptorSet;
include protocol PIPCBlobInputStream;
include protocol PParentToChildStream;
include IPCBlob;
namespace mozilla {
namespace ipc {
struct FileCreationSuccessResult
{
IPCBlob blob;
};
struct FileCreationErrorResult
{
nsresult errorCode;
};
union FileCreationResult
{
FileCreationSuccessResult;
FileCreationErrorResult;
};
protocol PFileCreator
{
manager PBackground;
child:
async __delete__(FileCreationResult aResult);
};
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -39,5 +39,5 @@ parent:
async OperationDone(nsCString aContentType, FileDescriptor aFD);
};
} // namespace dom
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -8,6 +8,8 @@ with Files("**"):
BUG_COMPONENT = ("Core", "DOM: File")
EXPORTS.mozilla.dom.ipc += [
'FileCreatorChild.h',
'FileCreatorParent.h',
'IPCBlobInputStream.h',
'IPCBlobInputStreamChild.h',
'IPCBlobInputStreamParent.h',
@ -23,6 +25,8 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
'FileCreatorChild.cpp',
'FileCreatorParent.cpp',
'IPCBlobInputStream.cpp',
'IPCBlobInputStreamChild.cpp',
'IPCBlobInputStreamParent.cpp',
@ -38,6 +42,7 @@ UNIFIED_SOURCES += [
IPDL_SOURCES += [
'BlobTypes.ipdlh',
'IPCBlob.ipdlh',
'PFileCreator.ipdl',
'PIPCBlobInputStream.ipdl',
'PPendingIPCBlob.ipdl',
'PTemporaryIPCBlob.ipdl',

Просмотреть файл

@ -72,12 +72,12 @@ class BlobImplSnapshot final : public BlobImpl, public PIBlobImplSnapshot {
virtual void GetMozFullPath(nsAString& aName,
SystemCallerGuarantee aGuarantee,
ErrorResult& aRv) const override {
ErrorResult& aRv) override {
mBlobImpl->GetMozFullPath(aName, aGuarantee, aRv);
}
virtual void GetMozFullPathInternal(nsAString& aFileName,
ErrorResult& aRv) const override {
ErrorResult& aRv) override {
mBlobImpl->GetMozFullPathInternal(aFileName, aRv);
}

Просмотреть файл

@ -39,7 +39,6 @@
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/ExternalHelperAppChild.h"
#include "mozilla/dom/FileCreatorHelper.h"
#include "mozilla/dom/GetFilesHelper.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/JSWindowActorService.h"
@ -3394,51 +3393,6 @@ bool ContentChild::DeallocPSessionStorageObserverChild(
return true;
}
void ContentChild::FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
const nsAString& aFullPath,
const nsAString& aType,
const nsAString& aName,
const Optional<int64_t>& aLastModified,
bool aExistenceCheck,
bool aIsFromNsIFile) {
MOZ_ASSERT(aHelper);
bool lastModifiedPassed = false;
int64_t lastModified = 0;
if (aLastModified.WasPassed()) {
lastModifiedPassed = true;
lastModified = aLastModified.Value();
}
Unused << SendFileCreationRequest(
aUUID, nsString(aFullPath), nsString(aType), nsString(aName),
lastModifiedPassed, lastModified, aExistenceCheck, aIsFromNsIFile);
mFileCreationPending.Put(aUUID, aHelper);
}
mozilla::ipc::IPCResult ContentChild::RecvFileCreationResponse(
const nsID& aUUID, const FileCreationResult& aResult) {
FileCreatorHelper* helper = mFileCreationPending.GetWeak(aUUID);
if (!helper) {
return IPC_FAIL_NO_REASON(this);
}
if (aResult.type() == FileCreationResult::TFileCreationErrorResult) {
helper->ResponseReceived(nullptr,
aResult.get_FileCreationErrorResult().errorCode());
} else {
MOZ_ASSERT(aResult.type() ==
FileCreationResult::TFileCreationSuccessResult);
RefPtr<BlobImpl> impl = IPCBlobUtils::Deserialize(
aResult.get_FileCreationSuccessResult().blob());
helper->ResponseReceived(impl, NS_OK);
}
mFileCreationPending.Remove(aUUID);
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvActivate(PBrowserChild* aTab) {
BrowserChild* tab = static_cast<BrowserChild*>(aTab);
return tab->RecvActivate();

Просмотреть файл

@ -77,7 +77,6 @@ class ConsoleListener;
class ClonedMessageData;
class BrowserChild;
class GetFilesHelperChild;
class FileCreatorHelper;
class ContentChild final : public PContentChild,
public nsIWindowProvider,
@ -562,9 +561,6 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvBlobURLUnregistration(const nsCString& aURI);
mozilla::ipc::IPCResult RecvFileCreationResponse(
const nsID& aUUID, const FileCreationResult& aResult);
mozilla::ipc::IPCResult RecvRequestMemoryReport(
const uint32_t& generation, const bool& anonymize,
const bool& minimizeMemoryUsage, const Maybe<FileDescriptor>& DMDFile);
@ -643,13 +639,6 @@ class ContentChild final : public PContentChild,
static void FatalErrorIfNotUsingGPUProcess(const char* const aErrorMsg,
base::ProcessId aOtherPid);
// This method is used by FileCreatorHelper for the creation of a BlobImpl.
void FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
const nsAString& aFullPath, const nsAString& aType,
const nsAString& aName,
const Optional<int64_t>& aLastModified,
bool aExistenceCheck, bool aIsFromNsIFile);
typedef std::function<void(PRFileDesc*)> AnonymousTemporaryFileCallback;
nsresult AsyncOpenAnonymousTemporaryFile(
const AnonymousTemporaryFileCallback& aCallback);
@ -802,10 +791,6 @@ class ContentChild final : public PContentChild,
// received.
nsRefPtrHashtable<nsIDHashKey, GetFilesHelperChild> mGetFilesPendingRequests;
// Hashtable to keep track of the pending file creation.
// These items are removed when RecvFileCreationResponse is received.
nsRefPtrHashtable<nsIDHashKey, FileCreatorHelper> mFileCreationPending;
nsClassHashtable<nsUint64HashKey, AnonymousTemporaryFileCallback>
mPendingAnonymousTemporaryFiles;

Просмотреть файл

@ -47,7 +47,6 @@
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileCreatorHelper.h"
#include "mozilla/dom/FileSystemSecurity.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/ExternalHelperAppParent.h"
@ -5533,49 +5532,6 @@ bool ContentParent::DeallocPSessionStorageObserverParent(
return mozilla::dom::DeallocPSessionStorageObserverParent(aActor);
}
mozilla::ipc::IPCResult ContentParent::RecvFileCreationRequest(
const nsID& aID, const nsString& aFullPath, const nsString& aType,
const nsString& aName, const bool& aLastModifiedPassed,
const int64_t& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
// We allow the creation of File via this IPC call only for the 'file' process
// or for testing.
if (!mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE) &&
!Preferences::GetBool("dom.file.createInChild", false)) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<BlobImpl> blobImpl;
nsresult rv = FileCreatorHelper::CreateBlobImplForIPC(
aFullPath, aType, aName, aLastModifiedPassed, aLastModified,
aExistenceCheck, aIsFromNsIFile, getter_AddRefs(blobImpl));
if (NS_WARN_IF(NS_FAILED(rv))) {
if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
MOZ_ASSERT(blobImpl);
IPCBlob ipcBlob;
rv = IPCBlobUtils::Serialize(blobImpl, this, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
if (!SendFileCreationResponse(aID, FileCreationSuccessResult(ipcBlob))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
nsresult ContentParent::SaveRecording(nsIFile* aFile, bool* aRetval) {
if (mRecordReplayState != eRecording) {
*aRetval = false;

Просмотреть файл

@ -1128,12 +1128,6 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvDeleteGetFilesRequest(const nsID& aID);
mozilla::ipc::IPCResult RecvFileCreationRequest(
const nsID& aID, const nsString& aFullPath, const nsString& aType,
const nsString& aName, const bool& aLastModifiedPassed,
const int64_t& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile);
mozilla::ipc::IPCResult RecvAccumulateChildHistograms(
InfallibleTArray<HistogramAccumulation>&& aAccumulations);
mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistograms(

Просмотреть файл

@ -203,22 +203,6 @@ union GetFilesResponseResult
GetFilesResponseFailure;
};
struct FileCreationSuccessResult
{
IPCBlob blob;
};
struct FileCreationErrorResult
{
nsresult errorCode;
};
union FileCreationResult
{
FileCreationSuccessResult;
FileCreationErrorResult;
};
struct BlobURLRegistrationData
{
nsCString url;
@ -670,8 +654,6 @@ child:
async GMPsChanged(GMPCapabilityData[] capabilities);
async FileCreationResponse(nsID aID, FileCreationResult aResult);
/**
* Sending an activate message moves focus to the child.
*/
@ -1206,11 +1188,6 @@ parent:
async GetFilesRequest(nsID aID, nsString aDirectory, bool aRecursiveFlag);
async DeleteGetFilesRequest(nsID aID);
async FileCreationRequest(nsID aID, nsString aFullPath, nsString aType,
nsString aName, bool lastModifiedPassed,
int64_t lastModified, bool aExistenceCheck,
bool aIsFromNsIFile);
async StoreAndBroadcastBlobURLRegistration(nsCString url, IPCBlob blob,
Principal principal);

Просмотреть файл

@ -27,9 +27,11 @@
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
#include "mozilla/dom/ipc/FileCreatorChild.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
#include "mozilla/dom/ipc/PendingIPCBlobChild.h"
#include "mozilla/dom/ipc/TemporaryIPCBlobChild.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/quota/PQuotaChild.h"
#include "mozilla/dom/RemoteWorkerChild.h"
#include "mozilla/dom/RemoteWorkerServiceChild.h"
@ -379,6 +381,18 @@ bool BackgroundChildImpl::DeallocPTemporaryIPCBlobChild(
return true;
}
PFileCreatorChild* BackgroundChildImpl::AllocPFileCreatorChild(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
return new mozilla::dom::FileCreatorChild();
}
bool BackgroundChildImpl::DeallocPFileCreatorChild(PFileCreatorChild* aActor) {
delete static_cast<mozilla::dom::FileCreatorChild*>(aActor);
return true;
}
PIPCBlobInputStreamChild* BackgroundChildImpl::AllocPIPCBlobInputStreamChild(
const nsID& aID, const uint64_t& aSize) {
// IPCBlobInputStreamChild is refcounted. Here it's created and in

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsRefPtrHashtable.h"
#include "nsAutoPtr.h"
namespace mozilla {
@ -126,6 +127,13 @@ class BackgroundChildImpl : public PBackgroundChild {
virtual bool DeallocPTemporaryIPCBlobChild(
PTemporaryIPCBlobChild* aActor) override;
virtual PFileCreatorChild* AllocPFileCreatorChild(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) override;
virtual bool DeallocPFileCreatorChild(PFileCreatorChild* aActor) override;
virtual mozilla::dom::PRemoteWorkerChild* AllocPRemoteWorkerChild(
const RemoteWorkerData& aData) override;

Просмотреть файл

@ -30,9 +30,11 @@
#include "mozilla/dom/StorageActivityService.h"
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/dom/ipc/FileCreatorParent.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
#include "mozilla/dom/ipc/PendingIPCBlobParent.h"
#include "mozilla/dom/ipc/TemporaryIPCBlobParent.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/localstorage/ActorsParent.h"
#include "mozilla/dom/quota/ActorsParent.h"
#include "mozilla/dom/simpledb/ActorsParent.h"
@ -56,6 +58,7 @@
#include "mozilla/dom/network/UDPSocketParent.h"
#include "mozilla/dom/WebAuthnTransactionParent.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs.h"
#include "nsNetUtil.h"
#include "nsIScriptSecurityManager.h"
#include "nsProxyRelease.h"
@ -538,6 +541,53 @@ bool BackgroundParentImpl::DeallocPSharedWorkerParent(
return true;
}
PFileCreatorParent* BackgroundParentImpl::AllocPFileCreatorParent(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
RefPtr<mozilla::dom::FileCreatorParent> actor =
new mozilla::dom::FileCreatorParent();
return actor.forget().take();
}
mozilla::ipc::IPCResult BackgroundParentImpl::RecvPFileCreatorConstructor(
PFileCreatorParent* aActor, const nsString& aFullPath,
const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
bool isFileRemoteType = false;
// If the ContentParent is null we are dealing with a same-process actor.
RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(this);
if (!parent) {
isFileRemoteType = true;
} else {
isFileRemoteType = parent->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE);
NS_ReleaseOnMainThreadSystemGroup("ContentParent release", parent.forget());
}
mozilla::dom::FileCreatorParent* actor =
static_cast<mozilla::dom::FileCreatorParent*>(aActor);
// We allow the creation of File via this IPC call only for the 'file' process
// or for testing.
if (!isFileRemoteType && !StaticPrefs::dom_file_createInChild()) {
Unused << mozilla::dom::FileCreatorParent::Send__delete__(
actor, FileCreationErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return IPC_OK();
}
return actor->CreateAndShareFile(aFullPath, aType, aName, aLastModified,
aExistenceCheck, aIsFromNsIFile);
}
bool BackgroundParentImpl::DeallocPFileCreatorParent(
PFileCreatorParent* aActor) {
RefPtr<mozilla::dom::FileCreatorParent> actor =
dont_AddRef(static_cast<mozilla::dom::FileCreatorParent*>(aActor));
return true;
}
PTemporaryIPCBlobParent* BackgroundParentImpl::AllocPTemporaryIPCBlobParent() {
return new mozilla::dom::TemporaryIPCBlobParent();
}

Просмотреть файл

@ -155,6 +155,19 @@ class BackgroundParentImpl : public PBackgroundParent {
virtual bool DeallocPTemporaryIPCBlobParent(
PTemporaryIPCBlobParent* aActor) override;
virtual PFileCreatorParent* AllocPFileCreatorParent(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) override;
virtual mozilla::ipc::IPCResult RecvPFileCreatorConstructor(
PFileCreatorParent* actor, const nsString& aFullPath,
const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) override;
virtual bool DeallocPFileCreatorParent(PFileCreatorParent* aActor) override;
virtual mozilla::dom::PRemoteWorkerParent* AllocPRemoteWorkerParent(
const RemoteWorkerData& aData) override;

Просмотреть файл

@ -29,6 +29,7 @@ include protocol PRemoteWorker;
include protocol PRemoteWorkerService;
include protocol PSharedWorker;
include protocol PTemporaryIPCBlob;
include protocol PFileCreator;
include protocol PMessagePort;
include protocol PCameras;
include protocol PMIDIManager;
@ -94,6 +95,7 @@ sync protocol PBackground
manages PRemoteWorkerService;
manages PSharedWorker;
manages PTemporaryIPCBlob;
manages PFileCreator;
manages PMessagePort;
manages PCameras;
manages PMIDIManager;
@ -197,6 +199,10 @@ parent:
async PTemporaryIPCBlob();
async PFileCreator(nsString aFullPath, nsString aType, nsString aName,
int64_t? lastModified, bool aExistenceCheck,
bool aIsFromNsIFile);
async PClientManager();
async PMIDIManager();
@ -228,6 +234,7 @@ child:
async PPendingIPCBlob(IPCBlob blob);
async PRemoteWorker(RemoteWorkerData data);
both:
// PIPCBlobInputStream is created on the parent side only if the child starts
// a migration.

Просмотреть файл

@ -29,6 +29,13 @@ DIRECT_CALL_OVERRIDES = {
"RemotePermissionRequest", "nsContentPermissionHelper.h"
),
("PFileCreator", "child"): (
"mozilla::dom::FileCreatorChild", "mozilla/dom/ipc/FileCreatorChild.h"
),
("PFileCreator", "parent"): (
"mozilla::dom::FileCreatorParent", "mozilla/dom/ipc/FileCreatorParent.h"
),
("PFileSystemRequest", "child"): (
"FileSystemTaskChildBase", "mozilla/dom/FileSystemTaskBase.h"
),

Просмотреть файл

@ -598,6 +598,14 @@ VARCACHE_PREF(
)
// Allow the content process to create a File from a path. This is allowed just
// on parent process, on 'file' Content process, or for testing.
VARCACHE_PREF(
"dom.file.createInChild",
dom_file_createInChild,
RelaxedAtomicBool, false
)
//---------------------------------------------------------------------------
// Extension prefs
//---------------------------------------------------------------------------