mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1335536 - File.createFromNsIFile and File.createFromFileName should be async - part 2 - code, r=smaug
This commit is contained in:
parent
3b9eaa7785
commit
ff2e202053
@ -36,6 +36,7 @@
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
#include "mozilla/dom/FileCreatorHelper.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
@ -589,34 +590,14 @@ File::CreateFromNsIFile(const GlobalObject& aGlobal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
|
||||
impl->InitializeChromeFile(window, aData, aBag, true, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(impl->IsFile());
|
||||
|
||||
if (aBag.mLastModified.WasPassed()) {
|
||||
impl->SetLastModified(aBag.mLastModified.Value());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<File> domFile = new File(aGlobal.GetAsSupports(), impl);
|
||||
promise->MaybeResolve(domFile);
|
||||
|
||||
RefPtr<Promise> promise =
|
||||
FileCreatorHelper::CreateFile(aGlobal, aData, aBag, true, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<Promise>
|
||||
File::CreateFromFileName(const GlobalObject& aGlobal,
|
||||
const nsAString& aData,
|
||||
const nsAString& aPath,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
@ -625,28 +606,14 @@ File::CreateFromFileName(const GlobalObject& aGlobal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
|
||||
impl->InitializeChromeFile(window, aData, aBag, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(impl->IsFile());
|
||||
|
||||
if (aBag.mLastModified.WasPassed()) {
|
||||
impl->SetLastModified(aBag.mLastModified.Value());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
nsCOMPtr<nsIFile> file;
|
||||
aRv = NS_NewLocalFile(aPath, false, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<File> domFile = new File(aGlobal.GetAsSupports(), impl);
|
||||
promise->MaybeResolve(domFile);
|
||||
|
||||
RefPtr<Promise> promise =
|
||||
FileCreatorHelper::CreateFile(aGlobal, file, aBag, false, aRv);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
|
@ -207,14 +207,14 @@ public:
|
||||
// ChromeOnly
|
||||
static already_AddRefed<Promise>
|
||||
CreateFromFileName(const GlobalObject& aGlobal,
|
||||
const nsAString& aData,
|
||||
const nsAString& aFilePath,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// ChromeOnly
|
||||
static already_AddRefed<Promise>
|
||||
CreateFromNsIFile(const GlobalObject& aGlobal,
|
||||
nsIFile* aData,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
|
||||
|
190
dom/file/FileCreatorHelper.cpp
Normal file
190
dom/file/FileCreatorHelper.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
/* -*- 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 "FileCreatorHelper.h"
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
// Undefine the macro of CreateFile to avoid FileCreatorHelper#CreateFile being
|
||||
// replaced by FileCreatorHelper#CreateFileW.
|
||||
#ifdef CreateFile
|
||||
#undef CreateFile
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* static */ already_AddRefed<Promise>
|
||||
FileCreatorHelper::CreateFile(const GlobalObject& aGlobal,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<Promise> promise = Promise::Create(global, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
// 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.
|
||||
|
||||
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, 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
cc->FileCreationRequest(uuid, this, path, aBag.mType, aBag.mName,
|
||||
aBag.mLastModified, aIsFromNsIFile);
|
||||
}
|
||||
|
||||
void
|
||||
FileCreatorHelper::ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv)
|
||||
{
|
||||
if (NS_FAILED(aRv)) {
|
||||
mPromise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
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 aIsFromNsIFile,
|
||||
BlobImpl** aBlobImpl)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_NewLocalFile(aPath, true, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return CreateBlobImpl(file, aType, aName, aLastModifiedPassed, aLastModified,
|
||||
aIsFromNsIFile, aBlobImpl);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
FileCreatorHelper::CreateBlobImpl(nsIFile* aFile,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
bool aLastModifiedPassed,
|
||||
int64_t aLastModified,
|
||||
bool aIsFromNsIFile,
|
||||
BlobImpl** aBlobImpl)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
88
dom/file/FileCreatorHelper.h
Normal file
88
dom/file/FileCreatorHelper.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* -*- 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_FileCreatorHelper_h
|
||||
#define mozilla_dom_FileCreatorHelper_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
// Undefine the macro of CreateFile to avoid FileCreatorHelper#CreateFile being
|
||||
// replaced by FileCreatorHelper#CreateFileW.
|
||||
#ifdef CreateFile
|
||||
#undef CreateFile
|
||||
#endif
|
||||
|
||||
class nsIFile;
|
||||
class nsPIDOMWindowInner;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct ChromeFilePropertyBag;
|
||||
class GlobalObject;
|
||||
class Promise;
|
||||
class File;
|
||||
|
||||
class FileCreatorHelper final
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(FileCreatorHelper);
|
||||
|
||||
static already_AddRefed<Promise>
|
||||
CreateFile(const GlobalObject& aGlobal,
|
||||
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 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 aIsFromNsIFile,
|
||||
BlobImpl** aBlobImpl);
|
||||
|
||||
FileCreatorHelper(Promise* aPromise, nsPIDOMWindowInner* aWindow);
|
||||
~FileCreatorHelper() = default;
|
||||
|
||||
void
|
||||
SendRequest(nsIFile* aFile, const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile, ErrorResult& aRv);
|
||||
|
||||
RefPtr<Promise> mPromise;
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
};
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_FileCreatorHelper_h
|
@ -323,63 +323,60 @@ MultipartBlobImpl::SetMutable(bool aMutable)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv)
|
||||
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) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return;
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
mName = aBag.mName;
|
||||
mContentType = aBag.mType;
|
||||
mName = aName;
|
||||
mContentType = aType;
|
||||
mIsFromNsIFile = aIsFromNsIFile;
|
||||
|
||||
bool exists;
|
||||
aRv = aFile->Exists(&exists);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
nsresult rv= aFile->Exists(&exists);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
aRv.Throw(NS_ERROR_FILE_NOT_FOUND);
|
||||
return;
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
bool isDir;
|
||||
aRv = aFile->IsDirectory(&isDir);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
rv = aFile->IsDirectory(&isDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (isDir) {
|
||||
aRv.Throw(NS_ERROR_FILE_IS_DIRECTORY);
|
||||
return;
|
||||
return NS_ERROR_FILE_IS_DIRECTORY;
|
||||
}
|
||||
|
||||
if (mName.IsEmpty()) {
|
||||
aFile->GetLeafName(mName);
|
||||
}
|
||||
|
||||
RefPtr<File> blob = File::CreateFromFile(aWindow, aFile);
|
||||
RefPtr<File> blob = File::CreateFromFile(nullptr, aFile);
|
||||
|
||||
// Pre-cache size.
|
||||
blob->GetSize(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
ErrorResult error;
|
||||
blob->GetSize(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
// Pre-cache modified date.
|
||||
blob->GetLastModified(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
blob->GetLastModified(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
// XXXkhuey this is terrible
|
||||
@ -391,23 +388,16 @@ MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
|
||||
mBlobImpls = blobSet.GetBlobImpls();
|
||||
|
||||
SetLengthAndModifiedDate(aRv);
|
||||
NS_WARNING_ASSERTION(!aRv.Failed(), "SetLengthAndModifiedDate failed");
|
||||
}
|
||||
|
||||
void
|
||||
MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file;
|
||||
aRv = NS_NewLocalFile(aData, false, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
SetLengthAndModifiedDate(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
InitializeChromeFile(aWindow, file, aBag, false, aRv);
|
||||
if (aLastModifiedPassed) {
|
||||
SetLastModified(aLastModified);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -60,16 +60,12 @@ public:
|
||||
bool aNativeEOL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void InitializeChromeFile(nsPIDOMWindowInner* aWindow,
|
||||
nsIFile* aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
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,
|
||||
|
@ -21,6 +21,7 @@ EXPORTS += [
|
||||
EXPORTS.mozilla.dom += [
|
||||
'BlobSet.h',
|
||||
'File.h',
|
||||
'FileCreatorHelper.h',
|
||||
'FileList.h',
|
||||
'FileReader.h',
|
||||
'MutableBlobStorage.h',
|
||||
@ -30,6 +31,7 @@ EXPORTS.mozilla.dom += [
|
||||
UNIFIED_SOURCES += [
|
||||
'BlobSet.cpp',
|
||||
'File.cpp',
|
||||
'FileCreatorHelper.cpp',
|
||||
'FileList.cpp',
|
||||
'FileReader.cpp',
|
||||
'MultipartBlobImpl.cpp',
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "mozilla/dom/DataTransfer.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/ExternalHelperAppChild.h"
|
||||
#include "mozilla/dom/FileCreatorHelper.h"
|
||||
#include "mozilla/dom/FlyWebPublishedServerIPC.h"
|
||||
#include "mozilla/dom/GetFilesHelper.h"
|
||||
#include "mozilla/dom/MemoryReportRequest.h"
|
||||
@ -3184,5 +3185,55 @@ ContentChild::GetConstructedEventTarget(const Message& aMsg)
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ContentChild::FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
|
||||
const nsAString& aFullPath,
|
||||
const nsAString& aType,
|
||||
const nsAString& aName,
|
||||
const Optional<int64_t>& aLastModified,
|
||||
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, 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);
|
||||
|
||||
PBlobChild* blobChild =
|
||||
aResult.get_FileCreationSuccessResult().blobChild();
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
RefPtr<BlobImpl> impl = static_cast<BlobChild*>(blobChild)->GetBlobImpl();
|
||||
helper->ResponseReceived(impl, NS_OK);
|
||||
}
|
||||
|
||||
mFileCreationPending.Remove(aUUID);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -49,6 +49,7 @@ class PStorageChild;
|
||||
class ClonedMessageData;
|
||||
class TabChild;
|
||||
class GetFilesHelperChild;
|
||||
class FileCreatorHelper;
|
||||
|
||||
class ContentChild final : public PContentChild
|
||||
, public nsIWindowProvider
|
||||
@ -588,6 +589,10 @@ public:
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvBlobURLUnregistration(const nsCString& aURI) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvFileCreationResponse(const nsID& aUUID,
|
||||
const FileCreationResult& aResult) override;
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvRequestMemoryReport(
|
||||
const uint32_t& generation,
|
||||
@ -629,6 +634,14 @@ public:
|
||||
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 aIsFromNsIFile);
|
||||
|
||||
private:
|
||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
void StartForceKillTimer();
|
||||
@ -693,6 +706,10 @@ private:
|
||||
// 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;
|
||||
|
||||
bool mShuttingDown;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "mozilla/dom/DataTransfer.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileCreatorHelper.h"
|
||||
#include "mozilla/dom/ExternalHelperAppParent.h"
|
||||
#include "mozilla/dom/GetFilesHelper.h"
|
||||
#include "mozilla/dom/GeolocationBinding.h"
|
||||
@ -4946,3 +4947,37 @@ ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables
|
||||
*aRv = uriClassifier->ClassifyLocalWithTables(uri, aTables, *aResults);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
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& aIsFromNsIFile)
|
||||
{
|
||||
RefPtr<BlobImpl> blobImpl;
|
||||
nsresult rv =
|
||||
FileCreatorHelper::CreateBlobImplForIPC(aFullPath, aType, aName,
|
||||
aLastModifiedPassed,
|
||||
aLastModified, 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);
|
||||
|
||||
BlobParent* blobParent = BlobParent::GetOrCreate(this, blobImpl);
|
||||
if (!SendFileCreationResponse(aID,
|
||||
FileCreationSuccessResult(blobParent, nullptr))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -1114,6 +1114,13 @@ private:
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvDeleteGetFilesRequest(const nsID& aID) override;
|
||||
|
||||
virtual 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& aIsFromNsIFile) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvAccumulateChildHistogram(
|
||||
InfallibleTArray<Accumulation>&& aAccumulations) override;
|
||||
virtual mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistogram(
|
||||
|
@ -314,6 +314,22 @@ union GetFilesResponseResult
|
||||
GetFilesResponseFailure;
|
||||
};
|
||||
|
||||
struct FileCreationSuccessResult
|
||||
{
|
||||
PBlob blob;
|
||||
};
|
||||
|
||||
struct FileCreationErrorResult
|
||||
{
|
||||
nsresult errorCode;
|
||||
};
|
||||
|
||||
union FileCreationResult
|
||||
{
|
||||
FileCreationSuccessResult;
|
||||
FileCreationErrorResult;
|
||||
};
|
||||
|
||||
struct BlobURLRegistrationData
|
||||
{
|
||||
nsCString url;
|
||||
@ -652,6 +668,8 @@ child:
|
||||
|
||||
async GMPsChanged(GMPCapabilityData[] capabilities);
|
||||
|
||||
async FileCreationResponse(nsID aID, FileCreationResult aResult);
|
||||
|
||||
parent:
|
||||
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
|
||||
|
||||
@ -1152,6 +1170,10 @@ 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 aIsFromNsIFile);
|
||||
|
||||
async StoreAndBroadcastBlobURLRegistration(nsCString url, PBlob blob,
|
||||
Principal principal);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user