123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744 |
- /* 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 "ActorsChild.h"
- #include "BackgroundChildImpl.h"
- #include "FileHandleBase.h"
- #include "FileRequestBase.h"
- #include "js/Date.h"
- #include "mozilla/dom/EncodingUtils.h"
- #include "mozilla/dom/File.h"
- #include "mozilla/dom/ipc/BlobChild.h"
- #include "MutableFileBase.h"
- #include "nsCOMPtr.h"
- #include "nsContentUtils.h"
- #include "nsString.h"
- #include "xpcpublic.h"
- #include "mozilla/dom/BindingUtils.h"
- namespace mozilla {
- namespace dom {
- /*******************************************************************************
- * Helpers
- ******************************************************************************/
- namespace {
- class MOZ_STACK_CLASS AutoSetCurrentFileHandle final
- {
- typedef mozilla::ipc::BackgroundChildImpl BackgroundChildImpl;
- FileHandleBase* const mFileHandle;
- FileHandleBase* mPreviousFileHandle;
- FileHandleBase** mThreadLocalSlot;
- public:
- explicit AutoSetCurrentFileHandle(FileHandleBase* aFileHandle)
- : mFileHandle(aFileHandle)
- , mPreviousFileHandle(nullptr)
- , mThreadLocalSlot(nullptr)
- {
- if (aFileHandle) {
- BackgroundChildImpl::ThreadLocal* threadLocal =
- BackgroundChildImpl::GetThreadLocalForCurrentThread();
- MOZ_ASSERT(threadLocal);
- // Hang onto this location for resetting later.
- mThreadLocalSlot = &threadLocal->mCurrentFileHandle;
- // Save the current value.
- mPreviousFileHandle = *mThreadLocalSlot;
- // Set the new value.
- *mThreadLocalSlot = aFileHandle;
- }
- }
- ~AutoSetCurrentFileHandle()
- {
- MOZ_ASSERT_IF(mThreadLocalSlot, mFileHandle);
- MOZ_ASSERT_IF(mThreadLocalSlot, *mThreadLocalSlot == mFileHandle);
- if (mThreadLocalSlot) {
- // Reset old value.
- *mThreadLocalSlot = mPreviousFileHandle;
- }
- }
- FileHandleBase*
- FileHandle() const
- {
- return mFileHandle;
- }
- };
- class MOZ_STACK_CLASS ResultHelper final
- : public FileRequestBase::ResultCallback
- {
- FileRequestBase* mFileRequest;
- AutoSetCurrentFileHandle mAutoFileHandle;
- union
- {
- File* mFile;
- const nsCString* mString;
- const FileRequestMetadata* mMetadata;
- const JS::Handle<JS::Value>* mJSValHandle;
- } mResult;
- enum
- {
- ResultTypeFile,
- ResultTypeString,
- ResultTypeMetadata,
- ResultTypeJSValHandle,
- } mResultType;
- public:
- ResultHelper(FileRequestBase* aFileRequest,
- FileHandleBase* aFileHandle,
- File* aResult)
- : mFileRequest(aFileRequest)
- , mAutoFileHandle(aFileHandle)
- , mResultType(ResultTypeFile)
- {
- MOZ_ASSERT(aFileRequest);
- MOZ_ASSERT(aFileHandle);
- MOZ_ASSERT(aResult);
- mResult.mFile = aResult;
- }
- ResultHelper(FileRequestBase* aFileRequest,
- FileHandleBase* aFileHandle,
- const nsCString* aResult)
- : mFileRequest(aFileRequest)
- , mAutoFileHandle(aFileHandle)
- , mResultType(ResultTypeString)
- {
- MOZ_ASSERT(aFileRequest);
- MOZ_ASSERT(aFileHandle);
- MOZ_ASSERT(aResult);
- mResult.mString = aResult;
- }
- ResultHelper(FileRequestBase* aFileRequest,
- FileHandleBase* aFileHandle,
- const FileRequestMetadata* aResult)
- : mFileRequest(aFileRequest)
- , mAutoFileHandle(aFileHandle)
- , mResultType(ResultTypeMetadata)
- {
- MOZ_ASSERT(aFileRequest);
- MOZ_ASSERT(aFileHandle);
- MOZ_ASSERT(aResult);
- mResult.mMetadata = aResult;
- }
- ResultHelper(FileRequestBase* aFileRequest,
- FileHandleBase* aFileHandle,
- const JS::Handle<JS::Value>* aResult)
- : mFileRequest(aFileRequest)
- , mAutoFileHandle(aFileHandle)
- , mResultType(ResultTypeJSValHandle)
- {
- MOZ_ASSERT(aFileRequest);
- MOZ_ASSERT(aFileHandle);
- MOZ_ASSERT(aResult);
- mResult.mJSValHandle = aResult;
- }
- FileRequestBase*
- FileRequest() const
- {
- return mFileRequest;
- }
- FileHandleBase*
- FileHandle() const
- {
- return mAutoFileHandle.FileHandle();
- }
- virtual nsresult
- GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) override
- {
- MOZ_ASSERT(aCx);
- MOZ_ASSERT(mFileRequest);
- switch (mResultType) {
- case ResultTypeFile:
- return GetResult(aCx, mResult.mFile, aResult);
- case ResultTypeString:
- return GetResult(aCx, mResult.mString, aResult);
- case ResultTypeMetadata:
- return GetResult(aCx, mResult.mMetadata, aResult);
- case ResultTypeJSValHandle:
- aResult.set(*mResult.mJSValHandle);
- return NS_OK;
- default:
- MOZ_CRASH("Unknown result type!");
- }
- MOZ_CRASH("Should never get here!");
- }
- private:
- nsresult
- GetResult(JSContext* aCx,
- File* aFile,
- JS::MutableHandle<JS::Value> aResult)
- {
- bool ok = GetOrCreateDOMReflector(aCx, aFile, aResult);
- if (NS_WARN_IF(!ok)) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- return NS_OK;
- }
- nsresult
- GetResult(JSContext* aCx,
- const nsCString* aString,
- JS::MutableHandle<JS::Value> aResult)
- {
- const nsCString& data = *aString;
- nsresult rv;
- if (!mFileRequest->HasEncoding()) {
- JS::Rooted<JSObject*> arrayBuffer(aCx);
- rv = nsContentUtils::CreateArrayBuffer(aCx, data, arrayBuffer.address());
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- aResult.setObject(*arrayBuffer);
- return NS_OK;
- }
- nsAutoCString encoding;
- // The BOM sniffing is baked into the "decode" part of the Encoding
- // Standard, which the File API references.
- if (!nsContentUtils::CheckForBOM(
- reinterpret_cast<const unsigned char *>(data.get()),
- data.Length(),
- encoding)) {
- // BOM sniffing failed. Try the API argument.
- if (!EncodingUtils::FindEncodingForLabel(mFileRequest->GetEncoding(),
- encoding)) {
- // API argument failed. Since we are dealing with a file system file,
- // we don't have a meaningful type attribute for the blob available,
- // so proceeding to the next step, which is defaulting to UTF-8.
- encoding.AssignLiteral("UTF-8");
- }
- }
- nsString tmpString;
- rv = nsContentUtils::ConvertStringFromEncoding(encoding, data, tmpString);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- if (NS_WARN_IF(!xpc::StringToJsval(aCx, tmpString, aResult))) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- return NS_OK;
- }
- nsresult
- GetResult(JSContext* aCx,
- const FileRequestMetadata* aMetadata,
- JS::MutableHandle<JS::Value> aResult)
- {
- JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
- if (NS_WARN_IF(!obj)) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- const FileRequestSize& size = aMetadata->size();
- if (size.type() != FileRequestSize::Tvoid_t) {
- MOZ_ASSERT(size.type() == FileRequestSize::Tuint64_t);
- JS::Rooted<JS::Value> number(aCx, JS_NumberValue(size.get_uint64_t()));
- if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "size", number, 0))) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- }
- const FileRequestLastModified& lastModified = aMetadata->lastModified();
- if (lastModified.type() != FileRequestLastModified::Tvoid_t) {
- MOZ_ASSERT(lastModified.type() == FileRequestLastModified::Tint64_t);
- JS::Rooted<JSObject*> date(aCx,
- JS::NewDateObject(aCx, JS::TimeClip(lastModified.get_int64_t())));
- if (NS_WARN_IF(!date)) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "lastModified", date, 0))) {
- return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
- }
- }
- aResult.setObject(*obj);
- return NS_OK;
- }
- };
- already_AddRefed<File>
- ConvertActorToFile(FileHandleBase* aFileHandle,
- const FileRequestGetFileResponse& aResponse)
- {
- auto* actor = static_cast<BlobChild*>(aResponse.fileChild());
- MutableFileBase* mutableFile = aFileHandle->MutableFile();
- MOZ_ASSERT(mutableFile);
- const FileRequestMetadata& metadata = aResponse.metadata();
- const FileRequestSize& size = metadata.size();
- MOZ_ASSERT(size.type() == FileRequestSize::Tuint64_t);
- const FileRequestLastModified& lastModified = metadata.lastModified();
- MOZ_ASSERT(lastModified.type() == FileRequestLastModified::Tint64_t);
- actor->SetMysteryBlobInfo(mutableFile->Name(),
- mutableFile->Type(),
- size.get_uint64_t(),
- lastModified.get_int64_t());
- RefPtr<BlobImpl> blobImpl = actor->GetBlobImpl();
- MOZ_ASSERT(blobImpl);
- RefPtr<File> file = mutableFile->CreateFileFor(blobImpl, aFileHandle);
- return file.forget();
- }
- void
- HandleSuccess(ResultHelper* aResultHelper)
- {
- MOZ_ASSERT(aResultHelper);
- RefPtr<FileRequestBase> fileRequest = aResultHelper->FileRequest();
- MOZ_ASSERT(fileRequest);
- fileRequest->AssertIsOnOwningThread();
- RefPtr<FileHandleBase> fileHandle = aResultHelper->FileHandle();
- MOZ_ASSERT(fileHandle);
- if (fileHandle->IsAborted()) {
- fileRequest->SetError(NS_ERROR_DOM_FILEHANDLE_ABORT_ERR);
- return;
- }
- MOZ_ASSERT(fileHandle->IsOpen());
- fileRequest->SetResultCallback(aResultHelper);
- MOZ_ASSERT(fileHandle->IsOpen() || fileHandle->IsAborted());
- }
- void
- HandleError(FileRequestBase* aFileRequest,
- nsresult aErrorCode,
- FileHandleBase* aFileHandle)
- {
- MOZ_ASSERT(aFileRequest);
- aFileRequest->AssertIsOnOwningThread();
- MOZ_ASSERT(NS_FAILED(aErrorCode));
- MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_FILEHANDLE);
- MOZ_ASSERT(aFileHandle);
- RefPtr<FileRequestBase> fileRequest = aFileRequest;
- RefPtr<FileHandleBase> fileHandle = aFileHandle;
- AutoSetCurrentFileHandle ascfh(aFileHandle);
- fileRequest->SetError(aErrorCode);
- MOZ_ASSERT(fileHandle->IsOpen() || fileHandle->IsAborted());
- }
- } // anonymous namespace
- /*******************************************************************************
- * BackgroundMutableFileChildBase
- ******************************************************************************/
- BackgroundMutableFileChildBase::BackgroundMutableFileChildBase(
- DEBUGONLY(PRThread* aOwningThread))
- : ThreadObject(DEBUGONLY(aOwningThread))
- , mMutableFile(nullptr)
- {
- AssertIsOnOwningThread();
- MOZ_COUNT_CTOR(BackgroundMutableFileChildBase);
- }
- BackgroundMutableFileChildBase::~BackgroundMutableFileChildBase()
- {
- AssertIsOnOwningThread();
- MOZ_COUNT_DTOR(BackgroundMutableFileChildBase);
- }
- void
- BackgroundMutableFileChildBase::EnsureDOMObject()
- {
- AssertIsOnOwningThread();
- if (mTemporaryStrongMutableFile) {
- return;
- }
- mTemporaryStrongMutableFile = CreateMutableFile();
- MOZ_ASSERT(mTemporaryStrongMutableFile);
- mTemporaryStrongMutableFile->AssertIsOnOwningThread();
- mMutableFile = mTemporaryStrongMutableFile;
- }
- void
- BackgroundMutableFileChildBase::ReleaseDOMObject()
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(mTemporaryStrongMutableFile);
- mTemporaryStrongMutableFile->AssertIsOnOwningThread();
- MOZ_ASSERT(mMutableFile == mTemporaryStrongMutableFile);
- mTemporaryStrongMutableFile = nullptr;
- }
- void
- BackgroundMutableFileChildBase::SendDeleteMeInternal()
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(!mTemporaryStrongMutableFile);
- if (mMutableFile) {
- mMutableFile->ClearBackgroundActor();
- mMutableFile = nullptr;
- MOZ_ALWAYS_TRUE(PBackgroundMutableFileChild::SendDeleteMe());
- }
- }
- void
- BackgroundMutableFileChildBase::ActorDestroy(ActorDestroyReason aWhy)
- {
- AssertIsOnOwningThread();
- if (mMutableFile) {
- mMutableFile->ClearBackgroundActor();
- DEBUGONLY(mMutableFile = nullptr;)
- }
- }
- PBackgroundFileHandleChild*
- BackgroundMutableFileChildBase::AllocPBackgroundFileHandleChild(
- const FileMode& aMode)
- {
- MOZ_CRASH("PBackgroundFileHandleChild actors should be manually "
- "constructed!");
- }
- bool
- BackgroundMutableFileChildBase::DeallocPBackgroundFileHandleChild(
- PBackgroundFileHandleChild* aActor)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(aActor);
- delete static_cast<BackgroundFileHandleChild*>(aActor);
- return true;
- }
- /*******************************************************************************
- * BackgroundFileHandleChild
- ******************************************************************************/
- BackgroundFileHandleChild::BackgroundFileHandleChild(
- DEBUGONLY(PRThread* aOwningThread,)
- FileHandleBase* aFileHandle)
- : ThreadObject(DEBUGONLY(aOwningThread))
- , mTemporaryStrongFileHandle(aFileHandle)
- , mFileHandle(aFileHandle)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(aFileHandle);
- aFileHandle->AssertIsOnOwningThread();
- MOZ_COUNT_CTOR(BackgroundFileHandleChild);
- }
- BackgroundFileHandleChild::~BackgroundFileHandleChild()
- {
- AssertIsOnOwningThread();
- MOZ_COUNT_DTOR(BackgroundFileHandleChild);
- }
- void
- BackgroundFileHandleChild::SendDeleteMeInternal()
- {
- AssertIsOnOwningThread();
- if (mFileHandle) {
- NoteActorDestroyed();
- MOZ_ALWAYS_TRUE(PBackgroundFileHandleChild::SendDeleteMe());
- }
- }
- void
- BackgroundFileHandleChild::NoteActorDestroyed()
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT_IF(mTemporaryStrongFileHandle, mFileHandle);
- if (mFileHandle) {
- mFileHandle->ClearBackgroundActor();
- // Normally this would be DEBUG-only but NoteActorDestroyed is also called
- // from SendDeleteMeInternal. In that case we're going to receive an actual
- // ActorDestroy call later and we don't want to touch a dead object.
- mTemporaryStrongFileHandle = nullptr;
- mFileHandle = nullptr;
- }
- }
- void
- BackgroundFileHandleChild::NoteComplete()
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT_IF(mFileHandle, mTemporaryStrongFileHandle);
- mTemporaryStrongFileHandle = nullptr;
- }
- void
- BackgroundFileHandleChild::ActorDestroy(ActorDestroyReason aWhy)
- {
- AssertIsOnOwningThread();
- NoteActorDestroyed();
- }
- bool
- BackgroundFileHandleChild::RecvComplete(const bool& aAborted)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(mFileHandle);
- mFileHandle->HandleCompleteOrAbort(aAborted);
- NoteComplete();
- return true;
- }
- PBackgroundFileRequestChild*
- BackgroundFileHandleChild::AllocPBackgroundFileRequestChild(
- const FileRequestParams& aParams)
- {
- MOZ_CRASH("PBackgroundFileRequestChild actors should be manually "
- "constructed!");
- }
- bool
- BackgroundFileHandleChild::DeallocPBackgroundFileRequestChild(
- PBackgroundFileRequestChild* aActor)
- {
- MOZ_ASSERT(aActor);
- delete static_cast<BackgroundFileRequestChild*>(aActor);
- return true;
- }
- /*******************************************************************************
- * BackgroundFileRequestChild
- ******************************************************************************/
- BackgroundFileRequestChild::BackgroundFileRequestChild(
- DEBUGONLY(PRThread* aOwningThread,)
- FileRequestBase* aFileRequest)
- : ThreadObject(DEBUGONLY(aOwningThread))
- , mFileRequest(aFileRequest)
- , mFileHandle(aFileRequest->FileHandle())
- , mActorDestroyed(false)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(aFileRequest);
- aFileRequest->AssertIsOnOwningThread();
- MOZ_ASSERT(mFileHandle);
- mFileHandle->AssertIsOnOwningThread();
- MOZ_COUNT_CTOR(BackgroundFileRequestChild);
- }
- BackgroundFileRequestChild::~BackgroundFileRequestChild()
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(!mFileHandle);
- MOZ_COUNT_DTOR(BackgroundFileRequestChild);
- }
- void
- BackgroundFileRequestChild::HandleResponse(nsresult aResponse)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(NS_FAILED(aResponse));
- MOZ_ASSERT(NS_ERROR_GET_MODULE(aResponse) == NS_ERROR_MODULE_DOM_FILEHANDLE);
- MOZ_ASSERT(mFileHandle);
- HandleError(mFileRequest, aResponse, mFileHandle);
- }
- void
- BackgroundFileRequestChild::HandleResponse(
- const FileRequestGetFileResponse& aResponse)
- {
- AssertIsOnOwningThread();
- RefPtr<File> file = ConvertActorToFile(mFileHandle, aResponse);
- ResultHelper helper(mFileRequest, mFileHandle, file);
- HandleSuccess(&helper);
- }
- void
- BackgroundFileRequestChild::HandleResponse(const nsCString& aResponse)
- {
- AssertIsOnOwningThread();
- ResultHelper helper(mFileRequest, mFileHandle, &aResponse);
- HandleSuccess(&helper);
- }
- void
- BackgroundFileRequestChild::HandleResponse(const FileRequestMetadata& aResponse)
- {
- AssertIsOnOwningThread();
- ResultHelper helper(mFileRequest, mFileHandle, &aResponse);
- HandleSuccess(&helper);
- }
- void
- BackgroundFileRequestChild::HandleResponse(JS::Handle<JS::Value> aResponse)
- {
- AssertIsOnOwningThread();
- ResultHelper helper(mFileRequest, mFileHandle, &aResponse);
- HandleSuccess(&helper);
- }
- void
- BackgroundFileRequestChild::ActorDestroy(ActorDestroyReason aWhy)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(!mActorDestroyed);
- mActorDestroyed = true;
- if (mFileHandle) {
- mFileHandle->AssertIsOnOwningThread();
- mFileHandle->OnRequestFinished(/* aActorDestroyedNormally */
- aWhy == Deletion);
- DEBUGONLY(mFileHandle = nullptr;)
- }
- }
- bool
- BackgroundFileRequestChild::Recv__delete__(const FileRequestResponse& aResponse)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(mFileRequest);
- MOZ_ASSERT(mFileHandle);
- if (mFileHandle->IsAborted()) {
- // Always handle an "error" with ABORT_ERR if the file handle was aborted,
- // even if the request succeeded or failed with another error.
- HandleResponse(NS_ERROR_DOM_FILEHANDLE_ABORT_ERR);
- } else {
- switch (aResponse.type()) {
- case FileRequestResponse::Tnsresult:
- HandleResponse(aResponse.get_nsresult());
- break;
- case FileRequestResponse::TFileRequestGetFileResponse:
- HandleResponse(aResponse.get_FileRequestGetFileResponse());
- break;
- case FileRequestResponse::TFileRequestReadResponse:
- HandleResponse(aResponse.get_FileRequestReadResponse().data());
- break;
- case FileRequestResponse::TFileRequestWriteResponse:
- HandleResponse(JS::UndefinedHandleValue);
- break;
- case FileRequestResponse::TFileRequestTruncateResponse:
- HandleResponse(JS::UndefinedHandleValue);
- break;
- case FileRequestResponse::TFileRequestFlushResponse:
- HandleResponse(JS::UndefinedHandleValue);
- break;
- case FileRequestResponse::TFileRequestGetMetadataResponse:
- HandleResponse(aResponse.get_FileRequestGetMetadataResponse()
- .metadata());
- break;
- default:
- MOZ_CRASH("Unknown response type!");
- }
- }
- mFileHandle->OnRequestFinished(/* aActorDestroyedNormally */ true);
- // Null this out so that we don't try to call OnRequestFinished() again in
- // ActorDestroy.
- mFileHandle = nullptr;
- return true;
- }
- bool
- BackgroundFileRequestChild::RecvProgress(const uint64_t& aProgress,
- const uint64_t& aProgressMax)
- {
- AssertIsOnOwningThread();
- MOZ_ASSERT(mFileRequest);
- mFileRequest->OnProgress(aProgress, aProgressMax);
- return true;
- }
- } // namespace dom
- } // namespace mozilla
|