LCOV - code coverage report
Current view: top level - dom/indexedDB - ActorsChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1944 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 251 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "ActorsChild.h"
       8             : 
       9             : #include "BackgroundChildImpl.h"
      10             : #include "FileSnapshot.h"
      11             : #include "IDBDatabase.h"
      12             : #include "IDBEvents.h"
      13             : #include "IDBFactory.h"
      14             : #include "IDBFileHandle.h"
      15             : #include "IDBIndex.h"
      16             : #include "IDBMutableFile.h"
      17             : #include "IDBObjectStore.h"
      18             : #include "IDBRequest.h"
      19             : #include "IDBTransaction.h"
      20             : #include "IndexedDatabase.h"
      21             : #include "IndexedDatabaseInlines.h"
      22             : #include "mozilla/BasicEvents.h"
      23             : #include "mozilla/CycleCollectedJSRuntime.h"
      24             : #include "mozilla/Maybe.h"
      25             : #include "mozilla/TypeTraits.h"
      26             : #include "mozilla/dom/Element.h"
      27             : #include "mozilla/dom/PermissionMessageUtils.h"
      28             : #include "mozilla/dom/TabChild.h"
      29             : #include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseFileChild.h"
      30             : #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
      31             : #include "mozilla/dom/ipc/PendingIPCBlobChild.h"
      32             : #include "mozilla/dom/IPCBlobUtils.h"
      33             : #include "mozilla/Encoding.h"
      34             : #include "mozilla/ipc/BackgroundUtils.h"
      35             : #include "mozilla/TaskQueue.h"
      36             : #include "nsCOMPtr.h"
      37             : #include "nsContentUtils.h"
      38             : #include "nsIAsyncInputStream.h"
      39             : #include "nsIBFCacheEntry.h"
      40             : #include "nsIDocument.h"
      41             : #include "nsIDOMEvent.h"
      42             : #include "nsIEventTarget.h"
      43             : #include "nsIFileStreams.h"
      44             : #include "nsNetCID.h"
      45             : #include "nsPIDOMWindow.h"
      46             : #include "nsThreadUtils.h"
      47             : #include "nsTraceRefcnt.h"
      48             : #include "PermissionRequestBase.h"
      49             : #include "ProfilerHelpers.h"
      50             : #include "ReportInternalError.h"
      51             : #include "WorkerPrivate.h"
      52             : #include "WorkerRunnable.h"
      53             : 
      54             : #ifdef DEBUG
      55             : #include "IndexedDatabaseManager.h"
      56             : #endif
      57             : 
      58             : #define GC_ON_IPC_MESSAGES 0
      59             : 
      60             : #if defined(DEBUG) || GC_ON_IPC_MESSAGES
      61             : 
      62             : #include "js/GCAPI.h"
      63             : #include "nsJSEnvironment.h"
      64             : 
      65             : #define BUILD_GC_ON_IPC_MESSAGES
      66             : 
      67             : #endif // DEBUG || GC_ON_IPC_MESSAGES
      68             : 
      69             : namespace mozilla {
      70             : 
      71             : using ipc::PrincipalInfo;
      72             : 
      73             : namespace dom {
      74             : 
      75             : using namespace workers;
      76             : 
      77             : namespace indexedDB {
      78             : 
      79             : /*******************************************************************************
      80             :  * ThreadLocal
      81             :  ******************************************************************************/
      82             : 
      83           0 : ThreadLocal::ThreadLocal(const nsID& aBackgroundChildLoggingId)
      84             :   : mLoggingInfo(aBackgroundChildLoggingId, 1, -1, 1)
      85           0 :   , mCurrentTransaction(0)
      86             : {
      87           0 :   MOZ_COUNT_CTOR(mozilla::dom::indexedDB::ThreadLocal);
      88             : 
      89             :   // NSID_LENGTH counts the null terminator, SetLength() does not.
      90           0 :   mLoggingIdString.SetLength(NSID_LENGTH - 1);
      91             : 
      92             :   aBackgroundChildLoggingId.ToProvidedString(
      93           0 :     *reinterpret_cast<char(*)[NSID_LENGTH]>(mLoggingIdString.BeginWriting()));
      94           0 : }
      95             : 
      96           0 : ThreadLocal::~ThreadLocal()
      97             : {
      98           0 :   MOZ_COUNT_DTOR(mozilla::dom::indexedDB::ThreadLocal);
      99           0 : }
     100             : 
     101             : /*******************************************************************************
     102             :  * Helpers
     103             :  ******************************************************************************/
     104             : 
     105             : namespace {
     106             : 
     107             : void
     108           0 : MaybeCollectGarbageOnIPCMessage()
     109             : {
     110             : #ifdef BUILD_GC_ON_IPC_MESSAGES
     111             :   static const bool kCollectGarbageOnIPCMessages =
     112             : #if GC_ON_IPC_MESSAGES
     113             :     true;
     114             : #else
     115             :     false;
     116             : #endif // GC_ON_IPC_MESSAGES
     117             : 
     118             :   if (!kCollectGarbageOnIPCMessages) {
     119           0 :     return;
     120             :   }
     121             : 
     122             :   static bool haveWarnedAboutGC = false;
     123             :   static bool haveWarnedAboutNonMainThread = false;
     124             : 
     125             :   if (!haveWarnedAboutGC) {
     126             :     haveWarnedAboutGC = true;
     127             :     NS_WARNING("IndexedDB child actor GC debugging enabled!");
     128             :   }
     129             : 
     130             :   if (!NS_IsMainThread()) {
     131             :     if (!haveWarnedAboutNonMainThread)  {
     132             :       haveWarnedAboutNonMainThread = true;
     133             :       NS_WARNING("Don't know how to GC on a non-main thread yet.");
     134             :     }
     135             :     return;
     136             :   }
     137             : 
     138             :   nsJSContext::GarbageCollectNow(JS::gcreason::DOM_IPC);
     139             :   nsJSContext::CycleCollectNow();
     140             : #endif // BUILD_GC_ON_IPC_MESSAGES
     141             : }
     142             : 
     143             : class MOZ_STACK_CLASS AutoSetCurrentTransaction final
     144             : {
     145             :   typedef mozilla::ipc::BackgroundChildImpl BackgroundChildImpl;
     146             : 
     147             :   IDBTransaction* const mTransaction;
     148             :   IDBTransaction* mPreviousTransaction;
     149             :   ThreadLocal* mThreadLocal;
     150             : 
     151             : public:
     152           0 :   explicit AutoSetCurrentTransaction(IDBTransaction* aTransaction)
     153           0 :     : mTransaction(aTransaction)
     154             :     , mPreviousTransaction(nullptr)
     155           0 :     , mThreadLocal(nullptr)
     156             :   {
     157           0 :     if (aTransaction) {
     158             :       BackgroundChildImpl::ThreadLocal* threadLocal =
     159           0 :         BackgroundChildImpl::GetThreadLocalForCurrentThread();
     160           0 :       MOZ_ASSERT(threadLocal);
     161             : 
     162             :       // Hang onto this for resetting later.
     163           0 :       mThreadLocal = threadLocal->mIndexedDBThreadLocal;
     164           0 :       MOZ_ASSERT(mThreadLocal);
     165             : 
     166             :       // Save the current value.
     167           0 :       mPreviousTransaction = mThreadLocal->GetCurrentTransaction();
     168             : 
     169             :       // Set the new value.
     170           0 :       mThreadLocal->SetCurrentTransaction(aTransaction);
     171             :     }
     172           0 :   }
     173             : 
     174           0 :   ~AutoSetCurrentTransaction()
     175           0 :   {
     176           0 :     MOZ_ASSERT_IF(mThreadLocal, mTransaction);
     177           0 :     MOZ_ASSERT_IF(mThreadLocal,
     178             :                   mThreadLocal->GetCurrentTransaction() == mTransaction);
     179             : 
     180           0 :     if (mThreadLocal) {
     181             :       // Reset old value.
     182           0 :       mThreadLocal->SetCurrentTransaction(mPreviousTransaction);
     183             :     }
     184           0 :   }
     185             : 
     186             :   IDBTransaction*
     187           0 :   Transaction() const
     188             :   {
     189           0 :     return mTransaction;
     190             :   }
     191             : };
     192             : 
     193           0 : class MOZ_STACK_CLASS ResultHelper final
     194             :   : public IDBRequest::ResultCallback
     195             : {
     196             :   IDBRequest* mRequest;
     197             :   AutoSetCurrentTransaction mAutoTransaction;
     198             : 
     199             :   union
     200             :   {
     201             :     IDBDatabase* mDatabase;
     202             :     IDBCursor* mCursor;
     203             :     IDBMutableFile* mMutableFile;
     204             :     StructuredCloneReadInfo* mStructuredClone;
     205             :     const nsTArray<StructuredCloneReadInfo>* mStructuredCloneArray;
     206             :     const Key* mKey;
     207             :     const nsTArray<Key>* mKeyArray;
     208             :     const JS::Value* mJSVal;
     209             :     const JS::Handle<JS::Value>* mJSValHandle;
     210             :   } mResult;
     211             : 
     212             :   enum
     213             :   {
     214             :     ResultTypeDatabase,
     215             :     ResultTypeCursor,
     216             :     ResultTypeMutableFile,
     217             :     ResultTypeStructuredClone,
     218             :     ResultTypeStructuredCloneArray,
     219             :     ResultTypeKey,
     220             :     ResultTypeKeyArray,
     221             :     ResultTypeJSVal,
     222             :     ResultTypeJSValHandle,
     223             :   } mResultType;
     224             : 
     225             : public:
     226           0 :   ResultHelper(IDBRequest* aRequest,
     227             :                IDBTransaction* aTransaction,
     228             :                IDBDatabase* aResult)
     229           0 :     : mRequest(aRequest)
     230             :     , mAutoTransaction(aTransaction)
     231           0 :     , mResultType(ResultTypeDatabase)
     232             :   {
     233           0 :     MOZ_ASSERT(aRequest);
     234           0 :     MOZ_ASSERT(aResult);
     235             : 
     236           0 :     mResult.mDatabase = aResult;
     237           0 :   }
     238             : 
     239           0 :   ResultHelper(IDBRequest* aRequest,
     240             :                IDBTransaction* aTransaction,
     241             :                IDBCursor* aResult)
     242           0 :     : mRequest(aRequest)
     243             :     , mAutoTransaction(aTransaction)
     244           0 :     , mResultType(ResultTypeCursor)
     245             :   {
     246           0 :     MOZ_ASSERT(aRequest);
     247             : 
     248           0 :     mResult.mCursor = aResult;
     249           0 :   }
     250             : 
     251           0 :   ResultHelper(IDBRequest* aRequest,
     252             :                IDBTransaction* aTransaction,
     253             :                IDBMutableFile* aResult)
     254           0 :     : mRequest(aRequest)
     255             :     , mAutoTransaction(aTransaction)
     256           0 :     , mResultType(ResultTypeMutableFile)
     257             :   {
     258           0 :     MOZ_ASSERT(aRequest);
     259             : 
     260           0 :     mResult.mMutableFile = aResult;
     261           0 :   }
     262             : 
     263           0 :   ResultHelper(IDBRequest* aRequest,
     264             :                IDBTransaction* aTransaction,
     265             :                StructuredCloneReadInfo* aResult)
     266           0 :     : mRequest(aRequest)
     267             :     , mAutoTransaction(aTransaction)
     268           0 :     , mResultType(ResultTypeStructuredClone)
     269             :   {
     270           0 :     MOZ_ASSERT(aRequest);
     271           0 :     MOZ_ASSERT(aResult);
     272             : 
     273           0 :     mResult.mStructuredClone = aResult;
     274           0 :   }
     275             : 
     276           0 :   ResultHelper(IDBRequest* aRequest,
     277             :                IDBTransaction* aTransaction,
     278             :                const nsTArray<StructuredCloneReadInfo>* aResult)
     279           0 :     : mRequest(aRequest)
     280             :     , mAutoTransaction(aTransaction)
     281           0 :     , mResultType(ResultTypeStructuredCloneArray)
     282             :   {
     283           0 :     MOZ_ASSERT(aRequest);
     284           0 :     MOZ_ASSERT(aResult);
     285             : 
     286           0 :     mResult.mStructuredCloneArray = aResult;
     287           0 :   }
     288             : 
     289           0 :   ResultHelper(IDBRequest* aRequest,
     290             :                IDBTransaction* aTransaction,
     291             :                const Key* aResult)
     292           0 :     : mRequest(aRequest)
     293             :     , mAutoTransaction(aTransaction)
     294           0 :     , mResultType(ResultTypeKey)
     295             :   {
     296           0 :     MOZ_ASSERT(aRequest);
     297           0 :     MOZ_ASSERT(aResult);
     298             : 
     299           0 :     mResult.mKey = aResult;
     300           0 :   }
     301             : 
     302           0 :   ResultHelper(IDBRequest* aRequest,
     303             :                IDBTransaction* aTransaction,
     304             :                const nsTArray<Key>* aResult)
     305           0 :     : mRequest(aRequest)
     306             :     , mAutoTransaction(aTransaction)
     307           0 :     , mResultType(ResultTypeKeyArray)
     308             :   {
     309           0 :     MOZ_ASSERT(aRequest);
     310           0 :     MOZ_ASSERT(aResult);
     311             : 
     312           0 :     mResult.mKeyArray = aResult;
     313           0 :   }
     314             : 
     315           0 :   ResultHelper(IDBRequest* aRequest,
     316             :                IDBTransaction* aTransaction,
     317             :                const JS::Value* aResult)
     318           0 :     : mRequest(aRequest)
     319             :     , mAutoTransaction(aTransaction)
     320           0 :     , mResultType(ResultTypeJSVal)
     321             :   {
     322           0 :     MOZ_ASSERT(aRequest);
     323           0 :     MOZ_ASSERT(!aResult->isGCThing());
     324             : 
     325           0 :     mResult.mJSVal = aResult;
     326           0 :   }
     327             : 
     328           0 :   ResultHelper(IDBRequest* aRequest,
     329             :                IDBTransaction* aTransaction,
     330             :                const JS::Handle<JS::Value>* aResult)
     331           0 :     : mRequest(aRequest)
     332             :     , mAutoTransaction(aTransaction)
     333           0 :     , mResultType(ResultTypeJSValHandle)
     334             :   {
     335           0 :     MOZ_ASSERT(aRequest);
     336             : 
     337           0 :     mResult.mJSValHandle = aResult;
     338           0 :   }
     339             : 
     340             :   IDBRequest*
     341           0 :   Request() const
     342             :   {
     343           0 :     return mRequest;
     344             :   }
     345             : 
     346             :   IDBTransaction*
     347           0 :   Transaction() const
     348             :   {
     349           0 :     return mAutoTransaction.Transaction();
     350             :   }
     351             : 
     352             :   virtual nsresult
     353           0 :   GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) override
     354             :   {
     355           0 :     MOZ_ASSERT(aCx);
     356           0 :     MOZ_ASSERT(mRequest);
     357             : 
     358           0 :     switch (mResultType) {
     359             :       case ResultTypeDatabase:
     360           0 :         return GetResult(aCx, mResult.mDatabase, aResult);
     361             : 
     362             :       case ResultTypeCursor:
     363           0 :         return GetResult(aCx, mResult.mCursor, aResult);
     364             : 
     365             :       case ResultTypeMutableFile:
     366           0 :         return GetResult(aCx, mResult.mMutableFile, aResult);
     367             : 
     368             :       case ResultTypeStructuredClone:
     369           0 :         return GetResult(aCx, mResult.mStructuredClone, aResult);
     370             : 
     371             :       case ResultTypeStructuredCloneArray:
     372           0 :         return GetResult(aCx, mResult.mStructuredCloneArray, aResult);
     373             : 
     374             :       case ResultTypeKey:
     375           0 :         return GetResult(aCx, mResult.mKey, aResult);
     376             : 
     377             :       case ResultTypeKeyArray:
     378           0 :         return GetResult(aCx, mResult.mKeyArray, aResult);
     379             : 
     380             :       case ResultTypeJSVal:
     381           0 :         aResult.set(*mResult.mJSVal);
     382           0 :         return NS_OK;
     383             : 
     384             :       case ResultTypeJSValHandle:
     385           0 :         aResult.set(*mResult.mJSValHandle);
     386           0 :         return NS_OK;
     387             : 
     388             :       default:
     389           0 :         MOZ_CRASH("Unknown result type!");
     390             :     }
     391             : 
     392             :     MOZ_CRASH("Should never get here!");
     393             :   }
     394             : 
     395             : private:
     396             :   template <class T>
     397             :   typename EnableIf<IsSame<T, IDBDatabase>::value ||
     398             :                     IsSame<T, IDBCursor>::value ||
     399             :                     IsSame<T, IDBMutableFile>::value,
     400             :                     nsresult>::Type
     401           0 :   GetResult(JSContext* aCx,
     402             :             T* aDOMObject,
     403             :             JS::MutableHandle<JS::Value> aResult)
     404             :   {
     405           0 :     if (!aDOMObject) {
     406           0 :       aResult.setNull();
     407           0 :       return NS_OK;
     408             :     }
     409             : 
     410           0 :     bool ok = GetOrCreateDOMReflector(aCx, aDOMObject, aResult);
     411           0 :     if (NS_WARN_IF(!ok)) {
     412           0 :       IDB_REPORT_INTERNAL_ERR();
     413           0 :       return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     414             :     }
     415             : 
     416           0 :     return NS_OK;
     417             :   }
     418             : 
     419             :   nsresult
     420           0 :   GetResult(JSContext* aCx,
     421             :             StructuredCloneReadInfo* aCloneInfo,
     422             :             JS::MutableHandle<JS::Value> aResult)
     423             :   {
     424           0 :     bool ok = IDBObjectStore::DeserializeValue(aCx, *aCloneInfo, aResult);
     425             : 
     426           0 :     if (NS_WARN_IF(!ok)) {
     427           0 :       return NS_ERROR_DOM_DATA_CLONE_ERR;
     428             :     }
     429             : 
     430           0 :     return NS_OK;
     431             :   }
     432             : 
     433             :   nsresult
     434           0 :   GetResult(JSContext* aCx,
     435             :             const nsTArray<StructuredCloneReadInfo>* aCloneInfos,
     436             :             JS::MutableHandle<JS::Value> aResult)
     437             :   {
     438           0 :     JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
     439           0 :     if (NS_WARN_IF(!array)) {
     440           0 :       IDB_REPORT_INTERNAL_ERR();
     441           0 :       return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     442             :     }
     443             : 
     444           0 :     if (!aCloneInfos->IsEmpty()) {
     445           0 :       const uint32_t count = aCloneInfos->Length();
     446             : 
     447           0 :       if (NS_WARN_IF(!JS_SetArrayLength(aCx, array, count))) {
     448           0 :         IDB_REPORT_INTERNAL_ERR();
     449           0 :         return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     450             :       }
     451             : 
     452           0 :       for (uint32_t index = 0; index < count; index++) {
     453             :         auto& cloneInfo =
     454           0 :           const_cast<StructuredCloneReadInfo&>(aCloneInfos->ElementAt(index));
     455             : 
     456           0 :         JS::Rooted<JS::Value> value(aCx);
     457             : 
     458           0 :         nsresult rv = GetResult(aCx, &cloneInfo, &value);
     459           0 :         if (NS_WARN_IF(NS_FAILED(rv))) {
     460           0 :           return rv;
     461             :         }
     462             : 
     463           0 :         if (NS_WARN_IF(!JS_DefineElement(aCx, array, index, value,
     464             :                                          JSPROP_ENUMERATE))) {
     465           0 :           IDB_REPORT_INTERNAL_ERR();
     466           0 :           return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     467             :         }
     468             :       }
     469             :     }
     470             : 
     471           0 :     aResult.setObject(*array);
     472           0 :     return NS_OK;
     473             :   }
     474             : 
     475             :   nsresult
     476           0 :   GetResult(JSContext* aCx,
     477             :             const Key* aKey,
     478             :             JS::MutableHandle<JS::Value> aResult)
     479             :   {
     480           0 :     nsresult rv = aKey->ToJSVal(aCx, aResult);
     481           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
     482           0 :       return rv;
     483             :     }
     484           0 :     return NS_OK;
     485             :   }
     486             : 
     487             :   nsresult
     488           0 :   GetResult(JSContext* aCx,
     489             :             const nsTArray<Key>* aKeys,
     490             :             JS::MutableHandle<JS::Value> aResult)
     491             :   {
     492           0 :     JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, 0));
     493           0 :     if (NS_WARN_IF(!array)) {
     494           0 :       IDB_REPORT_INTERNAL_ERR();
     495           0 :       return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     496             :     }
     497             : 
     498           0 :     if (!aKeys->IsEmpty()) {
     499           0 :       const uint32_t count = aKeys->Length();
     500             : 
     501           0 :       if (NS_WARN_IF(!JS_SetArrayLength(aCx, array, count))) {
     502           0 :         IDB_REPORT_INTERNAL_ERR();
     503           0 :         return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     504             :       }
     505             : 
     506           0 :       for (uint32_t index = 0; index < count; index++) {
     507           0 :         const Key& key = aKeys->ElementAt(index);
     508           0 :         MOZ_ASSERT(!key.IsUnset());
     509             : 
     510           0 :         JS::Rooted<JS::Value> value(aCx);
     511             : 
     512           0 :         nsresult rv = GetResult(aCx, &key, &value);
     513           0 :         if (NS_WARN_IF(NS_FAILED(rv))) {
     514           0 :           return rv;
     515             :         }
     516             : 
     517           0 :         if (NS_WARN_IF(!JS_DefineElement(aCx, array, index, value,
     518             :                                          JSPROP_ENUMERATE))) {
     519           0 :           IDB_REPORT_INTERNAL_ERR();
     520           0 :           return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
     521             :         }
     522             :       }
     523             :     }
     524             : 
     525           0 :     aResult.setObject(*array);
     526           0 :     return NS_OK;
     527             :   }
     528             : };
     529             : 
     530             : class PermissionRequestMainProcessHelper final
     531             :   : public PermissionRequestBase
     532             : {
     533             :   BackgroundFactoryRequestChild* mActor;
     534             :   RefPtr<IDBFactory> mFactory;
     535             : 
     536             : public:
     537           0 :   PermissionRequestMainProcessHelper(BackgroundFactoryRequestChild* aActor,
     538             :                                      IDBFactory* aFactory,
     539             :                                      Element* aOwnerElement,
     540             :                                      nsIPrincipal* aPrincipal)
     541           0 :     : PermissionRequestBase(aOwnerElement, aPrincipal)
     542             :     , mActor(aActor)
     543           0 :     , mFactory(aFactory)
     544             :   {
     545           0 :     MOZ_ASSERT(aActor);
     546           0 :     MOZ_ASSERT(aFactory);
     547           0 :     aActor->AssertIsOnOwningThread();
     548           0 :   }
     549             : 
     550             : protected:
     551           0 :   ~PermissionRequestMainProcessHelper()
     552           0 :   { }
     553             : 
     554             : private:
     555             :   virtual void
     556             :   OnPromptComplete(PermissionValue aPermissionValue) override;
     557             : };
     558             : 
     559             : class PermissionRequestChildProcessActor final
     560             :   : public PIndexedDBPermissionRequestChild
     561             : {
     562             :   BackgroundFactoryRequestChild* mActor;
     563             :   RefPtr<IDBFactory> mFactory;
     564             : 
     565             : public:
     566           0 :   PermissionRequestChildProcessActor(BackgroundFactoryRequestChild* aActor,
     567             :                                      IDBFactory* aFactory)
     568           0 :     : mActor(aActor)
     569           0 :     , mFactory(aFactory)
     570             :   {
     571           0 :     MOZ_ASSERT(aActor);
     572           0 :     MOZ_ASSERT(aFactory);
     573           0 :     aActor->AssertIsOnOwningThread();
     574           0 :   }
     575             : 
     576             : protected:
     577           0 :   ~PermissionRequestChildProcessActor()
     578           0 :   { }
     579             : 
     580             :   virtual mozilla::ipc::IPCResult
     581             :   Recv__delete__(const uint32_t& aPermission) override;
     582             : };
     583             : 
     584             : void
     585           0 : DeserializeStructuredCloneFiles(
     586             :                 IDBDatabase* aDatabase,
     587             :                 const nsTArray<SerializedStructuredCloneFile>& aSerializedFiles,
     588             :                 const nsTArray<RefPtr<JS::WasmModule>>* aModuleSet,
     589             :                 nsTArray<StructuredCloneFile>& aFiles)
     590             : {
     591           0 :   MOZ_ASSERT_IF(aModuleSet, !aModuleSet->IsEmpty());
     592           0 :   MOZ_ASSERT(aFiles.IsEmpty());
     593             : 
     594           0 :   if (!aSerializedFiles.IsEmpty()) {
     595           0 :     uint32_t moduleIndex = 0;
     596             : 
     597           0 :     const uint32_t count = aSerializedFiles.Length();
     598           0 :     aFiles.SetCapacity(count);
     599             : 
     600           0 :     for (uint32_t index = 0; index < count; index++) {
     601             :       const SerializedStructuredCloneFile& serializedFile =
     602           0 :         aSerializedFiles[index];
     603             : 
     604           0 :       const BlobOrMutableFile& blobOrMutableFile = serializedFile.file();
     605             : 
     606           0 :       switch (serializedFile.type()) {
     607             :         case StructuredCloneFile::eBlob: {
     608           0 :           MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob);
     609             : 
     610           0 :           const IPCBlob& ipcBlob = blobOrMutableFile.get_IPCBlob();
     611             : 
     612           0 :           RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(ipcBlob);
     613           0 :           MOZ_ASSERT(blobImpl);
     614             : 
     615           0 :           RefPtr<Blob> blob = Blob::Create(aDatabase->GetOwner(), blobImpl);
     616             : 
     617           0 :           StructuredCloneFile* file = aFiles.AppendElement();
     618           0 :           MOZ_ASSERT(file);
     619             : 
     620           0 :           file->mType = StructuredCloneFile::eBlob;
     621           0 :           file->mBlob.swap(blob);
     622             : 
     623           0 :           break;
     624             :         }
     625             : 
     626             :         case StructuredCloneFile::eMutableFile: {
     627           0 :           MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t ||
     628             :                      blobOrMutableFile.type() ==
     629             :                        BlobOrMutableFile::TPBackgroundMutableFileChild);
     630             : 
     631           0 :           switch (blobOrMutableFile.type()) {
     632             :             case BlobOrMutableFile::Tnull_t: {
     633           0 :               StructuredCloneFile* file = aFiles.AppendElement();
     634           0 :               MOZ_ASSERT(file);
     635             : 
     636           0 :               file->mType = StructuredCloneFile::eMutableFile;
     637             : 
     638           0 :               break;
     639             :             }
     640             : 
     641             :             case BlobOrMutableFile::TPBackgroundMutableFileChild: {
     642             :               auto* actor =
     643             :                 static_cast<BackgroundMutableFileChild*>(
     644           0 :                   blobOrMutableFile.get_PBackgroundMutableFileChild());
     645           0 :               MOZ_ASSERT(actor);
     646             : 
     647           0 :               actor->EnsureDOMObject();
     648             : 
     649             :               auto* mutableFile =
     650           0 :                 static_cast<IDBMutableFile*>(actor->GetDOMObject());
     651           0 :               MOZ_ASSERT(mutableFile);
     652             : 
     653           0 :               StructuredCloneFile* file = aFiles.AppendElement();
     654           0 :               MOZ_ASSERT(file);
     655             : 
     656           0 :               file->mType = StructuredCloneFile::eMutableFile;
     657           0 :               file->mMutableFile = mutableFile;
     658             : 
     659           0 :               actor->ReleaseDOMObject();
     660             : 
     661           0 :               break;
     662             :             }
     663             : 
     664             :             default:
     665           0 :               MOZ_CRASH("Should never get here!");
     666             :           }
     667             : 
     668           0 :           break;
     669             :         }
     670             : 
     671             :         case StructuredCloneFile::eStructuredClone: {
     672           0 :           StructuredCloneFile* file = aFiles.AppendElement();
     673           0 :           MOZ_ASSERT(file);
     674             : 
     675           0 :           file->mType = StructuredCloneFile::eStructuredClone;
     676             : 
     677           0 :           break;
     678             :         }
     679             : 
     680             :         case StructuredCloneFile::eWasmBytecode:
     681             :         case StructuredCloneFile::eWasmCompiled: {
     682           0 :           if (aModuleSet) {
     683           0 :             MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::Tnull_t);
     684             : 
     685           0 :             StructuredCloneFile* file = aFiles.AppendElement();
     686           0 :             MOZ_ASSERT(file);
     687             : 
     688           0 :             file->mType = serializedFile.type();
     689             : 
     690           0 :             MOZ_ASSERT(moduleIndex < aModuleSet->Length());
     691           0 :             file->mWasmModule = aModuleSet->ElementAt(moduleIndex);
     692             : 
     693           0 :             if (serializedFile.type() == StructuredCloneFile::eWasmCompiled) {
     694           0 :               moduleIndex++;
     695             :             }
     696             : 
     697           0 :             break;
     698             :           }
     699             : 
     700           0 :           MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob);
     701             : 
     702           0 :           const IPCBlob& ipcBlob = blobOrMutableFile.get_IPCBlob();
     703             : 
     704           0 :           RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(ipcBlob);
     705           0 :           MOZ_ASSERT(blobImpl);
     706             : 
     707           0 :           RefPtr<Blob> blob = Blob::Create(aDatabase->GetOwner(), blobImpl);
     708             : 
     709           0 :           StructuredCloneFile* file = aFiles.AppendElement();
     710           0 :           MOZ_ASSERT(file);
     711             : 
     712           0 :           file->mType = serializedFile.type();
     713           0 :           file->mBlob.swap(blob);
     714             : 
     715           0 :           break;
     716             :         }
     717             : 
     718             :         default:
     719           0 :           MOZ_CRASH("Should never get here!");
     720             :       }
     721             :     }
     722             :   }
     723           0 : }
     724             : 
     725             : void
     726           0 : DispatchErrorEvent(IDBRequest* aRequest,
     727             :                    nsresult aErrorCode,
     728             :                    IDBTransaction* aTransaction = nullptr,
     729             :                    nsIDOMEvent* aEvent = nullptr)
     730             : {
     731           0 :   MOZ_ASSERT(aRequest);
     732           0 :   aRequest->AssertIsOnOwningThread();
     733           0 :   MOZ_ASSERT(NS_FAILED(aErrorCode));
     734           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_INDEXEDDB);
     735             : 
     736           0 :   AUTO_PROFILER_LABEL("IndexedDB:DispatchErrorEvent", STORAGE);
     737             : 
     738           0 :   RefPtr<IDBRequest> request = aRequest;
     739           0 :   RefPtr<IDBTransaction> transaction = aTransaction;
     740             : 
     741           0 :   request->SetError(aErrorCode);
     742             : 
     743           0 :   nsCOMPtr<nsIDOMEvent> errorEvent;
     744           0 :   if (!aEvent) {
     745             :     // Make an error event and fire it at the target.
     746           0 :     errorEvent = CreateGenericEvent(request,
     747           0 :                                     nsDependentString(kErrorEventType),
     748             :                                     eDoesBubble,
     749           0 :                                     eCancelable);
     750           0 :     MOZ_ASSERT(errorEvent);
     751             : 
     752           0 :     aEvent = errorEvent;
     753             :   }
     754             : 
     755           0 :   Maybe<AutoSetCurrentTransaction> asct;
     756           0 :   if (aTransaction) {
     757           0 :     asct.emplace(aTransaction);
     758             :   }
     759             : 
     760           0 :   if (transaction) {
     761           0 :     IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
     762             :                    "Firing %s event with error 0x%x",
     763             :                  "IndexedDB %s: C T[%lld] R[%llu]: %s (0x%x)",
     764             :                  IDB_LOG_ID_STRING(),
     765             :                  transaction->LoggingSerialNumber(),
     766             :                  request->LoggingSerialNumber(),
     767             :                  IDB_LOG_STRINGIFY(aEvent, kErrorEventType),
     768             :                  aErrorCode);
     769             :   } else {
     770           0 :     IDB_LOG_MARK("IndexedDB %s: Child  Request[%llu]: "
     771             :                    "Firing %s event with error 0x%x",
     772             :                  "IndexedDB %s: C R[%llu]: %s (0x%x)",
     773             :                  IDB_LOG_ID_STRING(),
     774             :                  request->LoggingSerialNumber(),
     775             :                  IDB_LOG_STRINGIFY(aEvent, kErrorEventType),
     776             :                  aErrorCode);
     777             :   }
     778             : 
     779             :   bool doDefault;
     780           0 :   nsresult rv = request->DispatchEvent(aEvent, &doDefault);
     781           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     782           0 :     return;
     783             :   }
     784             : 
     785           0 :   MOZ_ASSERT(!transaction || transaction->IsOpen() || transaction->IsAborted());
     786             : 
     787             :   // Do not abort the transaction here if this request is failed due to the
     788             :   // abortion of its transaction to ensure that the correct error cause of
     789             :   // the abort event be set in IDBTransaction::FireCompleteOrAbortEvents() later.
     790           0 :   if (transaction && transaction->IsOpen() &&
     791             :       aErrorCode != NS_ERROR_DOM_INDEXEDDB_ABORT_ERR) {
     792           0 :     WidgetEvent* internalEvent = aEvent->WidgetEventPtr();
     793           0 :     MOZ_ASSERT(internalEvent);
     794             : 
     795           0 :     if (internalEvent->mFlags.mExceptionWasRaised) {
     796           0 :       transaction->Abort(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
     797           0 :     } else if (doDefault) {
     798           0 :       transaction->Abort(request);
     799             :     }
     800             :   }
     801             : }
     802             : 
     803             : void
     804           0 : DispatchSuccessEvent(ResultHelper* aResultHelper,
     805             :                      nsIDOMEvent* aEvent = nullptr)
     806             : {
     807           0 :   MOZ_ASSERT(aResultHelper);
     808             : 
     809           0 :   AUTO_PROFILER_LABEL("IndexedDB:DispatchSuccessEvent", STORAGE);
     810             : 
     811           0 :   RefPtr<IDBRequest> request = aResultHelper->Request();
     812           0 :   MOZ_ASSERT(request);
     813           0 :   request->AssertIsOnOwningThread();
     814             : 
     815           0 :   RefPtr<IDBTransaction> transaction = aResultHelper->Transaction();
     816             : 
     817           0 :   if (transaction && transaction->IsAborted()) {
     818           0 :     DispatchErrorEvent(request, transaction->AbortCode(), transaction);
     819           0 :     return;
     820             :   }
     821             : 
     822           0 :   nsCOMPtr<nsIDOMEvent> successEvent;
     823           0 :   if (!aEvent) {
     824           0 :     successEvent = CreateGenericEvent(request,
     825           0 :                                       nsDependentString(kSuccessEventType),
     826             :                                       eDoesNotBubble,
     827           0 :                                       eNotCancelable);
     828           0 :     MOZ_ASSERT(successEvent);
     829             : 
     830           0 :     aEvent = successEvent;
     831             :   }
     832             : 
     833           0 :   request->SetResultCallback(aResultHelper);
     834             : 
     835           0 :   MOZ_ASSERT(aEvent);
     836           0 :   MOZ_ASSERT_IF(transaction, transaction->IsOpen());
     837             : 
     838           0 :   if (transaction) {
     839           0 :     IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld] Request[%llu]: "
     840             :                    "Firing %s event",
     841             :                  "IndexedDB %s: C T[%lld] R[%llu]: %s",
     842             :                  IDB_LOG_ID_STRING(),
     843             :                  transaction->LoggingSerialNumber(),
     844             :                  request->LoggingSerialNumber(),
     845             :                  IDB_LOG_STRINGIFY(aEvent, kSuccessEventType));
     846             :   } else {
     847           0 :     IDB_LOG_MARK("IndexedDB %s: Child  Request[%llu]: Firing %s event",
     848             :                  "IndexedDB %s: C R[%llu]: %s",
     849             :                  IDB_LOG_ID_STRING(),
     850             :                  request->LoggingSerialNumber(),
     851             :                  IDB_LOG_STRINGIFY(aEvent, kSuccessEventType));
     852             :   }
     853             : 
     854             :   bool dummy;
     855           0 :   nsresult rv = request->DispatchEvent(aEvent, &dummy);
     856           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     857           0 :     return;
     858             :   }
     859             : 
     860           0 :   MOZ_ASSERT_IF(transaction,
     861             :                 transaction->IsOpen() || transaction->IsAborted());
     862             : 
     863           0 :   WidgetEvent* internalEvent = aEvent->WidgetEventPtr();
     864           0 :   MOZ_ASSERT(internalEvent);
     865             : 
     866           0 :   if (transaction &&
     867           0 :       transaction->IsOpen() &&
     868           0 :       internalEvent->mFlags.mExceptionWasRaised) {
     869           0 :     transaction->Abort(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
     870             :   }
     871             : }
     872             : 
     873             : PRFileDesc*
     874           0 : GetFileDescriptorFromStream(nsIInputStream* aStream)
     875             : {
     876           0 :   MOZ_ASSERT(aStream);
     877             : 
     878           0 :   nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(aStream);
     879           0 :   if (NS_WARN_IF(!fileMetadata)) {
     880           0 :     return nullptr;
     881             :   }
     882             : 
     883             :   PRFileDesc* fileDesc;
     884           0 :   nsresult rv = fileMetadata->GetFileDescriptor(&fileDesc);
     885           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
     886           0 :     return nullptr;
     887             :   }
     888             : 
     889           0 :   MOZ_ASSERT(fileDesc);
     890             : 
     891           0 :   return fileDesc;
     892             : }
     893             : 
     894             : class WorkerPermissionChallenge;
     895             : 
     896             : // This class calles WorkerPermissionChallenge::OperationCompleted() in the
     897             : // worker thread.
     898           0 : class WorkerPermissionOperationCompleted final : public WorkerControlRunnable
     899             : {
     900             :   RefPtr<WorkerPermissionChallenge> mChallenge;
     901             : 
     902             : public:
     903           0 :   WorkerPermissionOperationCompleted(WorkerPrivate* aWorkerPrivate,
     904             :                                      WorkerPermissionChallenge* aChallenge)
     905           0 :     : WorkerControlRunnable(aWorkerPrivate, WorkerThreadUnchangedBusyCount)
     906           0 :     , mChallenge(aChallenge)
     907             :   {
     908           0 :     MOZ_ASSERT(NS_IsMainThread());
     909           0 :   }
     910             : 
     911             :   virtual bool
     912             :   WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
     913             : };
     914             : 
     915             : // This class used to do prompting in the main thread and main process.
     916             : class WorkerPermissionRequest final : public PermissionRequestBase
     917             : {
     918             :   RefPtr<WorkerPermissionChallenge> mChallenge;
     919             : 
     920             : public:
     921           0 :   WorkerPermissionRequest(Element* aElement,
     922             :                           nsIPrincipal* aPrincipal,
     923             :                           WorkerPermissionChallenge* aChallenge)
     924           0 :     : PermissionRequestBase(aElement, aPrincipal)
     925           0 :     , mChallenge(aChallenge)
     926             :   {
     927           0 :     MOZ_ASSERT(XRE_IsParentProcess());
     928           0 :     MOZ_ASSERT(NS_IsMainThread());
     929           0 :     MOZ_ASSERT(aChallenge);
     930           0 :   }
     931             : 
     932             : private:
     933           0 :   ~WorkerPermissionRequest()
     934           0 :   {
     935           0 :     MOZ_ASSERT(NS_IsMainThread());
     936           0 :   }
     937             : 
     938             :   virtual void
     939             :   OnPromptComplete(PermissionValue aPermissionValue) override;
     940             : };
     941             : 
     942             : // This class is used in the main thread of all child processes.
     943             : class WorkerPermissionRequestChildProcessActor final
     944             :   : public PIndexedDBPermissionRequestChild
     945             : {
     946             :   RefPtr<WorkerPermissionChallenge> mChallenge;
     947             : 
     948             : public:
     949           0 :   explicit WorkerPermissionRequestChildProcessActor(
     950             :                                           WorkerPermissionChallenge* aChallenge)
     951           0 :     : mChallenge(aChallenge)
     952             :   {
     953           0 :     MOZ_ASSERT(!XRE_IsParentProcess());
     954           0 :     MOZ_ASSERT(NS_IsMainThread());
     955           0 :     MOZ_ASSERT(aChallenge);
     956           0 :   }
     957             : 
     958             : protected:
     959           0 :   ~WorkerPermissionRequestChildProcessActor()
     960           0 :   {}
     961             : 
     962             :   virtual mozilla::ipc::IPCResult
     963             :   Recv__delete__(const uint32_t& aPermission) override;
     964             : };
     965             : 
     966           0 : class WorkerPermissionChallenge final : public Runnable
     967             : {
     968             : public:
     969           0 :   WorkerPermissionChallenge(WorkerPrivate* aWorkerPrivate,
     970             :                             BackgroundFactoryRequestChild* aActor,
     971             :                             IDBFactory* aFactory,
     972             :                             const PrincipalInfo& aPrincipalInfo)
     973           0 :     : Runnable("indexedDB::WorkerPermissionChallenge")
     974             :     , mWorkerPrivate(aWorkerPrivate)
     975             :     , mActor(aActor)
     976             :     , mFactory(aFactory)
     977           0 :     , mPrincipalInfo(aPrincipalInfo)
     978             :   {
     979           0 :     MOZ_ASSERT(mWorkerPrivate);
     980           0 :     MOZ_ASSERT(aActor);
     981           0 :     MOZ_ASSERT(aFactory);
     982           0 :     mWorkerPrivate->AssertIsOnWorkerThread();
     983           0 :   }
     984             : 
     985             :   bool
     986           0 :   Dispatch()
     987             :   {
     988           0 :     mWorkerPrivate->AssertIsOnWorkerThread();
     989           0 :     if (NS_WARN_IF(!mWorkerPrivate->ModifyBusyCountFromWorker(true))) {
     990           0 :       return false;
     991             :     }
     992             : 
     993           0 :     if (NS_WARN_IF(NS_FAILED(mWorkerPrivate->DispatchToMainThread(this)))) {
     994           0 :       mWorkerPrivate->ModifyBusyCountFromWorker(false);
     995           0 :       return false;
     996             :     }
     997             : 
     998           0 :     return true;
     999             :   }
    1000             : 
    1001             :   NS_IMETHOD
    1002           0 :   Run() override
    1003             :   {
    1004           0 :     bool completed = RunInternal();
    1005           0 :     if (completed) {
    1006           0 :       OperationCompleted();
    1007             :     }
    1008             : 
    1009           0 :     return NS_OK;
    1010             :   }
    1011             : 
    1012             :   void
    1013           0 :   OperationCompleted()
    1014             :   {
    1015           0 :     if (NS_IsMainThread()) {
    1016             :       RefPtr<WorkerPermissionOperationCompleted> runnable =
    1017           0 :         new WorkerPermissionOperationCompleted(mWorkerPrivate, this);
    1018             : 
    1019           0 :       MOZ_ALWAYS_TRUE(runnable->Dispatch());
    1020           0 :       return;
    1021             :     }
    1022             : 
    1023           0 :     MOZ_ASSERT(mActor);
    1024           0 :     mActor->AssertIsOnOwningThread();
    1025             : 
    1026           0 :     MaybeCollectGarbageOnIPCMessage();
    1027             : 
    1028           0 :     RefPtr<IDBFactory> factory;
    1029           0 :     mFactory.swap(factory);
    1030             : 
    1031           0 :     mActor->SendPermissionRetry();
    1032           0 :     mActor = nullptr;
    1033             : 
    1034           0 :     mWorkerPrivate->AssertIsOnWorkerThread();
    1035           0 :     mWorkerPrivate->ModifyBusyCountFromWorker(false);
    1036             :   }
    1037             : 
    1038             : private:
    1039             :   bool
    1040           0 :   RunInternal()
    1041             :   {
    1042           0 :     MOZ_ASSERT(NS_IsMainThread());
    1043             : 
    1044             :     // Walk up to our containing page
    1045           0 :     WorkerPrivate* wp = mWorkerPrivate;
    1046           0 :     while (wp->GetParent()) {
    1047           0 :       wp = wp->GetParent();
    1048             :     }
    1049             : 
    1050           0 :     nsPIDOMWindowInner* window = wp->GetWindow();
    1051           0 :     if (!window) {
    1052           0 :       return true;
    1053             :     }
    1054             : 
    1055             :     nsresult rv;
    1056             :     nsCOMPtr<nsIPrincipal> principal =
    1057           0 :       mozilla::ipc::PrincipalInfoToPrincipal(mPrincipalInfo, &rv);
    1058           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
    1059           0 :       return true;
    1060             :     }
    1061             : 
    1062           0 :     if (XRE_IsParentProcess()) {
    1063             :       nsCOMPtr<Element> ownerElement =
    1064           0 :         do_QueryInterface(window->GetChromeEventHandler());
    1065           0 :       if (NS_WARN_IF(!ownerElement)) {
    1066           0 :         return true;
    1067             :       }
    1068             : 
    1069             :       RefPtr<WorkerPermissionRequest> helper =
    1070           0 :         new WorkerPermissionRequest(ownerElement, principal, this);
    1071             : 
    1072             :       PermissionRequestBase::PermissionValue permission;
    1073           0 :       if (NS_WARN_IF(NS_FAILED(helper->PromptIfNeeded(&permission)))) {
    1074           0 :         return true;
    1075             :       }
    1076             : 
    1077           0 :       MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed ||
    1078             :                  permission == PermissionRequestBase::kPermissionDenied ||
    1079             :                  permission == PermissionRequestBase::kPermissionPrompt);
    1080             : 
    1081           0 :       return permission != PermissionRequestBase::kPermissionPrompt;
    1082             :     }
    1083             : 
    1084           0 :     TabChild* tabChild = TabChild::GetFrom(window);
    1085           0 :     MOZ_ASSERT(tabChild);
    1086             : 
    1087           0 :     IPC::Principal ipcPrincipal(principal);
    1088             : 
    1089           0 :     auto* actor = new WorkerPermissionRequestChildProcessActor(this);
    1090           0 :     tabChild->SetEventTargetForActor(actor, wp->MainThreadEventTarget());
    1091           0 :     MOZ_ASSERT(actor->GetActorEventTarget());
    1092           0 :     tabChild->SendPIndexedDBPermissionRequestConstructor(actor, ipcPrincipal);
    1093           0 :     return false;
    1094             :   }
    1095             : 
    1096             : private:
    1097             :   WorkerPrivate* mWorkerPrivate;
    1098             :   BackgroundFactoryRequestChild* mActor;
    1099             :   RefPtr<IDBFactory> mFactory;
    1100             :   PrincipalInfo mPrincipalInfo;
    1101             : };
    1102             : 
    1103             : void
    1104           0 : WorkerPermissionRequest::OnPromptComplete(PermissionValue aPermissionValue)
    1105             : {
    1106           0 :   MOZ_ASSERT(NS_IsMainThread());
    1107           0 :   mChallenge->OperationCompleted();
    1108           0 : }
    1109             : 
    1110             : bool
    1111           0 : WorkerPermissionOperationCompleted::WorkerRun(JSContext* aCx,
    1112             :                                               WorkerPrivate* aWorkerPrivate)
    1113             : {
    1114           0 :   aWorkerPrivate->AssertIsOnWorkerThread();
    1115           0 :   mChallenge->OperationCompleted();
    1116           0 :   return true;
    1117             : }
    1118             : 
    1119             : mozilla::ipc::IPCResult
    1120           0 : WorkerPermissionRequestChildProcessActor::Recv__delete__(
    1121             :                                               const uint32_t& /* aPermission */)
    1122             : {
    1123           0 :   MOZ_ASSERT(NS_IsMainThread());
    1124           0 :   mChallenge->OperationCompleted();
    1125           0 :   return IPC_OK();
    1126             : }
    1127             : 
    1128             : class MOZ_STACK_CLASS AutoSetCurrentFileHandle final
    1129             : {
    1130             :   typedef mozilla::ipc::BackgroundChildImpl BackgroundChildImpl;
    1131             : 
    1132             :   IDBFileHandle* const mFileHandle;
    1133             :   IDBFileHandle* mPreviousFileHandle;
    1134             :   IDBFileHandle** mThreadLocalSlot;
    1135             : 
    1136             : public:
    1137           0 :   explicit AutoSetCurrentFileHandle(IDBFileHandle* aFileHandle)
    1138           0 :     : mFileHandle(aFileHandle)
    1139             :     , mPreviousFileHandle(nullptr)
    1140           0 :     , mThreadLocalSlot(nullptr)
    1141             :   {
    1142           0 :     if (aFileHandle) {
    1143             :       BackgroundChildImpl::ThreadLocal* threadLocal =
    1144           0 :         BackgroundChildImpl::GetThreadLocalForCurrentThread();
    1145           0 :       MOZ_ASSERT(threadLocal);
    1146             : 
    1147             :       // Hang onto this location for resetting later.
    1148           0 :       mThreadLocalSlot = &threadLocal->mCurrentFileHandle;
    1149             : 
    1150             :       // Save the current value.
    1151           0 :       mPreviousFileHandle = *mThreadLocalSlot;
    1152             : 
    1153             :       // Set the new value.
    1154           0 :       *mThreadLocalSlot = aFileHandle;
    1155             :     }
    1156           0 :   }
    1157             : 
    1158           0 :   ~AutoSetCurrentFileHandle()
    1159           0 :   {
    1160           0 :     MOZ_ASSERT_IF(mThreadLocalSlot, mFileHandle);
    1161           0 :     MOZ_ASSERT_IF(mThreadLocalSlot, *mThreadLocalSlot == mFileHandle);
    1162             : 
    1163           0 :     if (mThreadLocalSlot) {
    1164             :       // Reset old value.
    1165           0 :       *mThreadLocalSlot = mPreviousFileHandle;
    1166             :     }
    1167           0 :   }
    1168             : 
    1169             :   IDBFileHandle*
    1170           0 :   FileHandle() const
    1171             :   {
    1172           0 :     return mFileHandle;
    1173             :   }
    1174             : };
    1175             : 
    1176           0 : class MOZ_STACK_CLASS FileHandleResultHelper final
    1177             :   : public IDBFileRequest::ResultCallback
    1178             : {
    1179             :   IDBFileRequest* mFileRequest;
    1180             :   AutoSetCurrentFileHandle mAutoFileHandle;
    1181             : 
    1182             :   union
    1183             :   {
    1184             :     File* mFile;
    1185             :     const nsCString* mString;
    1186             :     const FileRequestMetadata* mMetadata;
    1187             :     const JS::Handle<JS::Value>* mJSValHandle;
    1188             :   } mResult;
    1189             : 
    1190             :   enum
    1191             :   {
    1192             :     ResultTypeFile,
    1193             :     ResultTypeString,
    1194             :     ResultTypeMetadata,
    1195             :     ResultTypeJSValHandle,
    1196             :   } mResultType;
    1197             : 
    1198             : public:
    1199           0 :   FileHandleResultHelper(IDBFileRequest* aFileRequest,
    1200             :                          IDBFileHandle* aFileHandle,
    1201             :                          File* aResult)
    1202           0 :     : mFileRequest(aFileRequest)
    1203             :     , mAutoFileHandle(aFileHandle)
    1204           0 :     , mResultType(ResultTypeFile)
    1205             :   {
    1206           0 :     MOZ_ASSERT(aFileRequest);
    1207           0 :     MOZ_ASSERT(aFileHandle);
    1208           0 :     MOZ_ASSERT(aResult);
    1209             : 
    1210           0 :     mResult.mFile = aResult;
    1211           0 :   }
    1212             : 
    1213           0 :   FileHandleResultHelper(IDBFileRequest* aFileRequest,
    1214             :                          IDBFileHandle* aFileHandle,
    1215             :                          const nsCString* aResult)
    1216           0 :     : mFileRequest(aFileRequest)
    1217             :     , mAutoFileHandle(aFileHandle)
    1218           0 :     , mResultType(ResultTypeString)
    1219             :   {
    1220           0 :     MOZ_ASSERT(aFileRequest);
    1221           0 :     MOZ_ASSERT(aFileHandle);
    1222           0 :     MOZ_ASSERT(aResult);
    1223             : 
    1224           0 :     mResult.mString = aResult;
    1225           0 :   }
    1226             : 
    1227           0 :   FileHandleResultHelper(IDBFileRequest* aFileRequest,
    1228             :                          IDBFileHandle* aFileHandle,
    1229             :                          const FileRequestMetadata* aResult)
    1230           0 :     : mFileRequest(aFileRequest)
    1231             :     , mAutoFileHandle(aFileHandle)
    1232           0 :     , mResultType(ResultTypeMetadata)
    1233             :   {
    1234           0 :     MOZ_ASSERT(aFileRequest);
    1235           0 :     MOZ_ASSERT(aFileHandle);
    1236           0 :     MOZ_ASSERT(aResult);
    1237             : 
    1238           0 :     mResult.mMetadata = aResult;
    1239           0 :   }
    1240             : 
    1241             : 
    1242           0 :   FileHandleResultHelper(IDBFileRequest* aFileRequest,
    1243             :                          IDBFileHandle* aFileHandle,
    1244             :                          const JS::Handle<JS::Value>* aResult)
    1245           0 :     : mFileRequest(aFileRequest)
    1246             :     , mAutoFileHandle(aFileHandle)
    1247           0 :     , mResultType(ResultTypeJSValHandle)
    1248             :   {
    1249           0 :     MOZ_ASSERT(aFileRequest);
    1250           0 :     MOZ_ASSERT(aFileHandle);
    1251           0 :     MOZ_ASSERT(aResult);
    1252             : 
    1253           0 :     mResult.mJSValHandle = aResult;
    1254           0 :   }
    1255             : 
    1256             :   IDBFileRequest*
    1257           0 :   FileRequest() const
    1258             :   {
    1259           0 :     return mFileRequest;
    1260             :   }
    1261             : 
    1262             :   IDBFileHandle*
    1263           0 :   FileHandle() const
    1264             :   {
    1265           0 :     return mAutoFileHandle.FileHandle();
    1266             :   }
    1267             : 
    1268             :   virtual nsresult
    1269           0 :   GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult) override
    1270             :   {
    1271           0 :     MOZ_ASSERT(aCx);
    1272           0 :     MOZ_ASSERT(mFileRequest);
    1273             : 
    1274           0 :     switch (mResultType) {
    1275             :       case ResultTypeFile:
    1276           0 :         return GetResult(aCx, mResult.mFile, aResult);
    1277             : 
    1278             :       case ResultTypeString:
    1279           0 :         return GetResult(aCx, mResult.mString, aResult);
    1280             : 
    1281             :       case ResultTypeMetadata:
    1282           0 :         return GetResult(aCx, mResult.mMetadata, aResult);
    1283             : 
    1284             :       case ResultTypeJSValHandle:
    1285           0 :         aResult.set(*mResult.mJSValHandle);
    1286           0 :         return NS_OK;
    1287             : 
    1288             :       default:
    1289           0 :         MOZ_CRASH("Unknown result type!");
    1290             :     }
    1291             : 
    1292             :     MOZ_CRASH("Should never get here!");
    1293             :   }
    1294             : 
    1295             : private:
    1296             :   nsresult
    1297           0 :   GetResult(JSContext* aCx,
    1298             :             File* aFile,
    1299             :             JS::MutableHandle<JS::Value> aResult)
    1300             :   {
    1301           0 :     bool ok = GetOrCreateDOMReflector(aCx, aFile, aResult);
    1302           0 :     if (NS_WARN_IF(!ok)) {
    1303           0 :       return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1304             :     }
    1305             : 
    1306           0 :     return NS_OK;
    1307             :   }
    1308             : 
    1309             :   nsresult
    1310           0 :   GetResult(JSContext* aCx,
    1311             :             const nsCString* aString,
    1312             :             JS::MutableHandle<JS::Value> aResult)
    1313             :   {
    1314           0 :     const nsCString& data = *aString;
    1315             : 
    1316             :     nsresult rv;
    1317             : 
    1318           0 :     if (!mFileRequest->HasEncoding()) {
    1319           0 :       JS::Rooted<JSObject*> arrayBuffer(aCx);
    1320           0 :       rv = nsContentUtils::CreateArrayBuffer(aCx, data, arrayBuffer.address());
    1321           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
    1322           0 :         return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1323             :       }
    1324             : 
    1325           0 :       aResult.setObject(*arrayBuffer);
    1326           0 :       return NS_OK;
    1327             :     }
    1328             : 
    1329             :     // Try the API argument.
    1330             :     const Encoding* encoding =
    1331           0 :       Encoding::ForLabel(mFileRequest->GetEncoding());
    1332           0 :     if (!encoding) {
    1333             :       // API argument failed. Since we are dealing with a file system file,
    1334             :       // we don't have a meaningful type attribute for the blob available,
    1335             :       // so proceeding to the next step, which is defaulting to UTF-8.
    1336           0 :       encoding = UTF_8_ENCODING;
    1337             :     }
    1338             : 
    1339           0 :     nsString tmpString;
    1340           0 :     Tie(rv, encoding) = encoding->Decode(data, tmpString);
    1341           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
    1342           0 :       return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1343             :     }
    1344           0 :     rv = NS_OK;
    1345             : 
    1346           0 :     if (NS_WARN_IF(!xpc::StringToJsval(aCx, tmpString, aResult))) {
    1347           0 :       return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1348             :     }
    1349             : 
    1350           0 :     return NS_OK;
    1351             :   }
    1352             : 
    1353             :   nsresult
    1354           0 :   GetResult(JSContext* aCx,
    1355             :             const FileRequestMetadata* aMetadata,
    1356             :             JS::MutableHandle<JS::Value> aResult)
    1357             :   {
    1358           0 :     JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
    1359           0 :     if (NS_WARN_IF(!obj)) {
    1360           0 :       return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1361             :     }
    1362             : 
    1363           0 :     const FileRequestSize& size = aMetadata->size();
    1364           0 :     if (size.type() != FileRequestSize::Tvoid_t) {
    1365           0 :       MOZ_ASSERT(size.type() == FileRequestSize::Tuint64_t);
    1366             : 
    1367           0 :       JS::Rooted<JS::Value> number(aCx, JS_NumberValue(size.get_uint64_t()));
    1368             : 
    1369           0 :       if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "size", number, 0))) {
    1370           0 :         return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1371             :       }
    1372             :     }
    1373             : 
    1374           0 :     const FileRequestLastModified& lastModified = aMetadata->lastModified();
    1375           0 :     if (lastModified.type() != FileRequestLastModified::Tvoid_t) {
    1376           0 :       MOZ_ASSERT(lastModified.type() == FileRequestLastModified::Tint64_t);
    1377             : 
    1378             :       JS::Rooted<JSObject*> date(aCx,
    1379           0 :         JS::NewDateObject(aCx, JS::TimeClip(lastModified.get_int64_t())));
    1380           0 :       if (NS_WARN_IF(!date)) {
    1381           0 :         return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1382             :       }
    1383             : 
    1384           0 :       if (NS_WARN_IF(!JS_DefineProperty(aCx, obj, "lastModified", date, 0))) {
    1385           0 :         return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
    1386             :       }
    1387             :     }
    1388             : 
    1389           0 :     aResult.setObject(*obj);
    1390           0 :     return NS_OK;
    1391             :   }
    1392             : };
    1393             : 
    1394             : already_AddRefed<File>
    1395           0 : ConvertActorToFile(IDBFileHandle* aFileHandle,
    1396             :                    const FileRequestGetFileResponse& aResponse)
    1397             : {
    1398           0 :   auto* actor = static_cast<PendingIPCBlobChild*>(aResponse.fileChild());
    1399             : 
    1400           0 :   IDBMutableFile* mutableFile = aFileHandle->GetMutableFile();
    1401           0 :   MOZ_ASSERT(mutableFile);
    1402             : 
    1403           0 :   const FileRequestMetadata& metadata = aResponse.metadata();
    1404             : 
    1405           0 :   const FileRequestSize& size = metadata.size();
    1406           0 :   MOZ_ASSERT(size.type() == FileRequestSize::Tuint64_t);
    1407             : 
    1408           0 :   const FileRequestLastModified& lastModified = metadata.lastModified();
    1409           0 :   MOZ_ASSERT(lastModified.type() == FileRequestLastModified::Tint64_t);
    1410             : 
    1411             :   RefPtr<BlobImpl> blobImpl =
    1412           0 :     actor->SetPendingInfoAndDeleteActor(mutableFile->Name(),
    1413             :                                         mutableFile->Type(),
    1414           0 :                                         size.get_uint64_t(),
    1415           0 :                                         lastModified.get_int64_t());
    1416           0 :   MOZ_ASSERT(blobImpl);
    1417             : 
    1418             :   RefPtr<BlobImpl> blobImplSnapshot =
    1419           0 :     new BlobImplSnapshot(blobImpl, static_cast<IDBFileHandle*>(aFileHandle));
    1420             : 
    1421           0 :   RefPtr<File> file = File::Create(mutableFile->GetOwner(), blobImplSnapshot);
    1422           0 :   return file.forget();
    1423             : }
    1424             : 
    1425             : void
    1426           0 : DispatchFileHandleErrorEvent(IDBFileRequest* aFileRequest,
    1427             :                              nsresult aErrorCode,
    1428             :                              IDBFileHandle* aFileHandle)
    1429             : {
    1430           0 :   MOZ_ASSERT(aFileRequest);
    1431           0 :   aFileRequest->AssertIsOnOwningThread();
    1432           0 :   MOZ_ASSERT(NS_FAILED(aErrorCode));
    1433           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aErrorCode) == NS_ERROR_MODULE_DOM_FILEHANDLE);
    1434           0 :   MOZ_ASSERT(aFileHandle);
    1435             : 
    1436           0 :   RefPtr<IDBFileRequest> fileRequest = aFileRequest;
    1437           0 :   RefPtr<IDBFileHandle> fileHandle = aFileHandle;
    1438             : 
    1439           0 :   AutoSetCurrentFileHandle ascfh(aFileHandle);
    1440             : 
    1441           0 :   fileRequest->FireError(aErrorCode);
    1442             : 
    1443           0 :   MOZ_ASSERT(fileHandle->IsOpen() || fileHandle->IsAborted());
    1444           0 : }
    1445             : 
    1446             : void
    1447           0 : DispatchFileHandleSuccessEvent(FileHandleResultHelper* aResultHelper)
    1448             : {
    1449           0 :   MOZ_ASSERT(aResultHelper);
    1450             : 
    1451           0 :   RefPtr<IDBFileRequest> fileRequest = aResultHelper->FileRequest();
    1452           0 :   MOZ_ASSERT(fileRequest);
    1453           0 :   fileRequest->AssertIsOnOwningThread();
    1454             : 
    1455           0 :   RefPtr<IDBFileHandle> fileHandle = aResultHelper->FileHandle();
    1456           0 :   MOZ_ASSERT(fileHandle);
    1457             : 
    1458           0 :   if (fileHandle->IsAborted()) {
    1459           0 :     fileRequest->FireError(NS_ERROR_DOM_FILEHANDLE_ABORT_ERR);
    1460           0 :     return;
    1461             :   }
    1462             : 
    1463           0 :   MOZ_ASSERT(fileHandle->IsOpen());
    1464             : 
    1465           0 :   fileRequest->SetResultCallback(aResultHelper);
    1466             : 
    1467           0 :   MOZ_ASSERT(fileHandle->IsOpen() || fileHandle->IsAborted());
    1468             : }
    1469             : 
    1470             : } // namespace
    1471             : 
    1472             : /*******************************************************************************
    1473             :  * Actor class declarations
    1474             :  ******************************************************************************/
    1475             : 
    1476             : // CancelableRunnable is used to make workers happy.
    1477             : class BackgroundRequestChild::PreprocessHelper final
    1478             :   : public CancelableRunnable
    1479             :   , public nsIInputStreamCallback
    1480             : {
    1481             :   typedef std::pair<nsCOMPtr<nsIInputStream>,
    1482             :                     nsCOMPtr<nsIInputStream>> StreamPair;
    1483             : 
    1484             :   nsCOMPtr<nsIEventTarget> mOwningEventTarget;
    1485             :   nsTArray<StreamPair> mStreamPairs;
    1486             :   nsTArray<RefPtr<JS::WasmModule>> mModuleSet;
    1487             :   BackgroundRequestChild* mActor;
    1488             : 
    1489             :   // These 2 are populated when the processing of the stream pairs runs.
    1490             :   PRFileDesc* mCurrentBytecodeFileDesc;
    1491             :   PRFileDesc* mCurrentCompiledFileDesc;
    1492             : 
    1493             :   RefPtr<TaskQueue> mTaskQueue;
    1494             :   nsCOMPtr<nsIEventTarget> mTaskQueueEventTarget;
    1495             : 
    1496             :   uint32_t mModuleSetIndex;
    1497             :   nsresult mResultCode;
    1498             : 
    1499             : public:
    1500           0 :   PreprocessHelper(uint32_t aModuleSetIndex, BackgroundRequestChild* aActor)
    1501           0 :     : CancelableRunnable("indexedDB::BackgroundRequestChild::PreprocessHelper")
    1502           0 :     , mOwningEventTarget(aActor->GetActorEventTarget())
    1503             :     , mActor(aActor)
    1504             :     , mCurrentBytecodeFileDesc(nullptr)
    1505             :     , mCurrentCompiledFileDesc(nullptr)
    1506             :     , mModuleSetIndex(aModuleSetIndex)
    1507           0 :     , mResultCode(NS_OK)
    1508             :   {
    1509           0 :     AssertIsOnOwningThread();
    1510           0 :     MOZ_ASSERT(aActor);
    1511           0 :     aActor->AssertIsOnOwningThread();
    1512           0 :   }
    1513             : 
    1514             :   bool
    1515           0 :   IsOnOwningThread() const
    1516             :   {
    1517           0 :     MOZ_ASSERT(mOwningEventTarget);
    1518             : 
    1519             :     bool current;
    1520           0 :     return NS_SUCCEEDED(mOwningEventTarget->IsOnCurrentThread(&current)) && current;
    1521             :   }
    1522             : 
    1523             :   void
    1524           0 :   AssertIsOnOwningThread() const
    1525             :   {
    1526           0 :     MOZ_ASSERT(IsOnOwningThread());
    1527           0 :   }
    1528             : 
    1529             :   void
    1530           0 :   ClearActor()
    1531             :   {
    1532           0 :     AssertIsOnOwningThread();
    1533             : 
    1534           0 :     mActor = nullptr;
    1535           0 :   }
    1536             : 
    1537             :   nsresult
    1538             :   Init(const nsTArray<StructuredCloneFile>& aFiles);
    1539             : 
    1540             :   nsresult
    1541             :   Dispatch();
    1542             : 
    1543             : private:
    1544           0 :   ~PreprocessHelper()
    1545           0 :   {
    1546           0 :     if (mTaskQueue) {
    1547           0 :       mTaskQueue->BeginShutdown();
    1548             :     }
    1549           0 :   }
    1550             : 
    1551             :   void
    1552             :   RunOnOwningThread();
    1553             : 
    1554             :   void
    1555             :   ProcessCurrentStreamPair();
    1556             : 
    1557             :   nsresult
    1558             :   WaitForStreamReady(nsIInputStream* aInputStream);
    1559             : 
    1560             :   void
    1561             :   ContinueWithStatus(nsresult aStatus);
    1562             : 
    1563             :   NS_DECL_ISUPPORTS_INHERITED
    1564             :   NS_DECL_NSIRUNNABLE
    1565             :   NS_DECL_NSIINPUTSTREAMCALLBACK
    1566             : 
    1567             :   virtual nsresult
    1568             :   Cancel() override;
    1569             : };
    1570             : 
    1571             : /*******************************************************************************
    1572             :  * Local class implementations
    1573             :  ******************************************************************************/
    1574             : 
    1575             : void
    1576           0 : PermissionRequestMainProcessHelper::OnPromptComplete(
    1577             :                                                PermissionValue aPermissionValue)
    1578             : {
    1579           0 :   MOZ_ASSERT(mActor);
    1580           0 :   mActor->AssertIsOnOwningThread();
    1581             : 
    1582           0 :   MaybeCollectGarbageOnIPCMessage();
    1583             : 
    1584           0 :   mActor->SendPermissionRetry();
    1585             : 
    1586           0 :   mActor = nullptr;
    1587           0 :   mFactory = nullptr;
    1588           0 : }
    1589             : 
    1590             : mozilla::ipc::IPCResult
    1591           0 : PermissionRequestChildProcessActor::Recv__delete__(
    1592             :                                               const uint32_t& /* aPermission */)
    1593             : {
    1594           0 :   MOZ_ASSERT(mActor);
    1595           0 :   mActor->AssertIsOnOwningThread();
    1596           0 :   MOZ_ASSERT(mFactory);
    1597             : 
    1598           0 :   MaybeCollectGarbageOnIPCMessage();
    1599             : 
    1600           0 :   RefPtr<IDBFactory> factory;
    1601           0 :   mFactory.swap(factory);
    1602             : 
    1603           0 :   mActor->SendPermissionRetry();
    1604           0 :   mActor = nullptr;
    1605             : 
    1606           0 :   return IPC_OK();
    1607             : }
    1608             : 
    1609             : /*******************************************************************************
    1610             :  * BackgroundRequestChildBase
    1611             :  ******************************************************************************/
    1612             : 
    1613           0 : BackgroundRequestChildBase::BackgroundRequestChildBase(IDBRequest* aRequest)
    1614           0 :   : mRequest(aRequest)
    1615             : {
    1616           0 :   MOZ_ASSERT(aRequest);
    1617           0 :   aRequest->AssertIsOnOwningThread();
    1618             : 
    1619           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundRequestChildBase);
    1620           0 : }
    1621             : 
    1622           0 : BackgroundRequestChildBase::~BackgroundRequestChildBase()
    1623             : {
    1624           0 :   AssertIsOnOwningThread();
    1625             : 
    1626           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundRequestChildBase);
    1627           0 : }
    1628             : 
    1629             : #ifdef DEBUG
    1630             : 
    1631             : void
    1632           0 : BackgroundRequestChildBase::AssertIsOnOwningThread() const
    1633             : {
    1634           0 :   MOZ_ASSERT(mRequest);
    1635           0 :   mRequest->AssertIsOnOwningThread();
    1636           0 : }
    1637             : 
    1638             : #endif // DEBUG
    1639             : 
    1640             : /*******************************************************************************
    1641             :  * BackgroundFactoryChild
    1642             :  ******************************************************************************/
    1643             : 
    1644           0 : BackgroundFactoryChild::BackgroundFactoryChild(IDBFactory* aFactory)
    1645           0 :   : mFactory(aFactory)
    1646             : {
    1647           0 :   AssertIsOnOwningThread();
    1648           0 :   MOZ_ASSERT(aFactory);
    1649           0 :   aFactory->AssertIsOnOwningThread();
    1650             : 
    1651           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundFactoryChild);
    1652           0 : }
    1653             : 
    1654           0 : BackgroundFactoryChild::~BackgroundFactoryChild()
    1655             : {
    1656           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundFactoryChild);
    1657           0 : }
    1658             : 
    1659             : void
    1660           0 : BackgroundFactoryChild::SendDeleteMeInternal()
    1661             : {
    1662           0 :   AssertIsOnOwningThread();
    1663             : 
    1664           0 :   if (mFactory) {
    1665           0 :     mFactory->ClearBackgroundActor();
    1666           0 :     mFactory = nullptr;
    1667             : 
    1668           0 :     MOZ_ALWAYS_TRUE(PBackgroundIDBFactoryChild::SendDeleteMe());
    1669             :   }
    1670           0 : }
    1671             : 
    1672             : void
    1673           0 : BackgroundFactoryChild::ActorDestroy(ActorDestroyReason aWhy)
    1674             : {
    1675           0 :   AssertIsOnOwningThread();
    1676             : 
    1677           0 :   MaybeCollectGarbageOnIPCMessage();
    1678             : 
    1679           0 :   if (mFactory) {
    1680           0 :     mFactory->ClearBackgroundActor();
    1681             : #ifdef DEBUG
    1682           0 :     mFactory = nullptr;
    1683             : #endif
    1684             :   }
    1685           0 : }
    1686             : 
    1687             : PBackgroundIDBFactoryRequestChild*
    1688           0 : BackgroundFactoryChild::AllocPBackgroundIDBFactoryRequestChild(
    1689             :                                             const FactoryRequestParams& aParams)
    1690             : {
    1691           0 :   MOZ_CRASH("PBackgroundIDBFactoryRequestChild actors should be manually "
    1692             :             "constructed!");
    1693             : }
    1694             : 
    1695             : bool
    1696           0 : BackgroundFactoryChild::DeallocPBackgroundIDBFactoryRequestChild(
    1697             :                                       PBackgroundIDBFactoryRequestChild* aActor)
    1698             : {
    1699           0 :   MOZ_ASSERT(aActor);
    1700             : 
    1701           0 :   delete static_cast<BackgroundFactoryRequestChild*>(aActor);
    1702           0 :   return true;
    1703             : }
    1704             : 
    1705             : PBackgroundIDBDatabaseChild*
    1706           0 : BackgroundFactoryChild::AllocPBackgroundIDBDatabaseChild(
    1707             :                                     const DatabaseSpec& aSpec,
    1708             :                                     PBackgroundIDBFactoryRequestChild* aRequest)
    1709             : {
    1710           0 :   AssertIsOnOwningThread();
    1711             : 
    1712           0 :   auto request = static_cast<BackgroundFactoryRequestChild*>(aRequest);
    1713           0 :   MOZ_ASSERT(request);
    1714             : 
    1715           0 :   return new BackgroundDatabaseChild(aSpec, request);
    1716             : }
    1717             : 
    1718             : bool
    1719           0 : BackgroundFactoryChild::DeallocPBackgroundIDBDatabaseChild(
    1720             :                                             PBackgroundIDBDatabaseChild* aActor)
    1721             : {
    1722           0 :   MOZ_ASSERT(aActor);
    1723             : 
    1724           0 :   delete static_cast<BackgroundDatabaseChild*>(aActor);
    1725           0 :   return true;
    1726             : }
    1727             : 
    1728             : mozilla::ipc::IPCResult
    1729           0 : BackgroundFactoryChild::RecvPBackgroundIDBDatabaseConstructor(
    1730             :                                     PBackgroundIDBDatabaseChild* aActor,
    1731             :                                     const DatabaseSpec& aSpec,
    1732             :                                     PBackgroundIDBFactoryRequestChild* aRequest)
    1733             : {
    1734           0 :   AssertIsOnOwningThread();
    1735           0 :   MOZ_ASSERT(aActor);
    1736           0 :   MOZ_ASSERT(aActor->GetActorEventTarget(),
    1737             :     "The event target shall be inherited from its manager actor.");
    1738             : 
    1739           0 :   return IPC_OK();
    1740             : }
    1741             : 
    1742             : /*******************************************************************************
    1743             :  * BackgroundFactoryRequestChild
    1744             :  ******************************************************************************/
    1745             : 
    1746           0 : BackgroundFactoryRequestChild::BackgroundFactoryRequestChild(
    1747             :                                                IDBFactory* aFactory,
    1748             :                                                IDBOpenDBRequest* aOpenRequest,
    1749             :                                                bool aIsDeleteOp,
    1750           0 :                                                uint64_t aRequestedVersion)
    1751             :   : BackgroundRequestChildBase(aOpenRequest)
    1752             :   , mFactory(aFactory)
    1753             :   , mRequestedVersion(aRequestedVersion)
    1754           0 :   , mIsDeleteOp(aIsDeleteOp)
    1755             : {
    1756             :   // Can't assert owning thread here because IPDL has not yet set our manager!
    1757           0 :   MOZ_ASSERT(aFactory);
    1758           0 :   aFactory->AssertIsOnOwningThread();
    1759           0 :   MOZ_ASSERT(aOpenRequest);
    1760             : 
    1761           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundFactoryRequestChild);
    1762           0 : }
    1763             : 
    1764           0 : BackgroundFactoryRequestChild::~BackgroundFactoryRequestChild()
    1765             : {
    1766           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundFactoryRequestChild);
    1767           0 : }
    1768             : 
    1769             : IDBOpenDBRequest*
    1770           0 : BackgroundFactoryRequestChild::GetOpenDBRequest() const
    1771             : {
    1772           0 :   AssertIsOnOwningThread();
    1773             : 
    1774           0 :   return static_cast<IDBOpenDBRequest*>(mRequest.get());
    1775             : }
    1776             : 
    1777             : bool
    1778           0 : BackgroundFactoryRequestChild::HandleResponse(nsresult aResponse)
    1779             : {
    1780           0 :   AssertIsOnOwningThread();
    1781           0 :   MOZ_ASSERT(NS_FAILED(aResponse));
    1782           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aResponse) == NS_ERROR_MODULE_DOM_INDEXEDDB);
    1783             : 
    1784           0 :   mRequest->Reset();
    1785             : 
    1786           0 :   DispatchErrorEvent(mRequest, aResponse);
    1787             : 
    1788           0 :   return true;
    1789             : }
    1790             : 
    1791             : bool
    1792           0 : BackgroundFactoryRequestChild::HandleResponse(
    1793             :                                    const OpenDatabaseRequestResponse& aResponse)
    1794             : {
    1795           0 :   AssertIsOnOwningThread();
    1796             : 
    1797           0 :   mRequest->Reset();
    1798             : 
    1799             :   auto databaseActor =
    1800           0 :     static_cast<BackgroundDatabaseChild*>(aResponse.databaseChild());
    1801           0 :   MOZ_ASSERT(databaseActor);
    1802             : 
    1803           0 :   IDBDatabase* database = databaseActor->GetDOMObject();
    1804           0 :   if (!database) {
    1805           0 :     databaseActor->EnsureDOMObject();
    1806             : 
    1807           0 :     database = databaseActor->GetDOMObject();
    1808           0 :     MOZ_ASSERT(database);
    1809             : 
    1810           0 :     MOZ_ASSERT(!database->IsClosed());
    1811             :   }
    1812             : 
    1813           0 :   if (database->IsClosed()) {
    1814             :     // If the database was closed already, which is only possible if we fired an
    1815             :     // "upgradeneeded" event, then we shouldn't fire a "success" event here.
    1816             :     // Instead we fire an error event with AbortErr.
    1817           0 :     DispatchErrorEvent(mRequest, NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
    1818             :   } else {
    1819           0 :     ResultHelper helper(mRequest, nullptr, database);
    1820             : 
    1821           0 :     DispatchSuccessEvent(&helper);
    1822             :   }
    1823             : 
    1824           0 :   databaseActor->ReleaseDOMObject();
    1825             : 
    1826           0 :   return true;
    1827             : }
    1828             : 
    1829             : bool
    1830           0 : BackgroundFactoryRequestChild::HandleResponse(
    1831             :                                  const DeleteDatabaseRequestResponse& aResponse)
    1832             : {
    1833           0 :   AssertIsOnOwningThread();
    1834             : 
    1835           0 :   ResultHelper helper(mRequest, nullptr, &JS::UndefinedHandleValue);
    1836             : 
    1837             :   nsCOMPtr<nsIDOMEvent> successEvent =
    1838           0 :     IDBVersionChangeEvent::Create(mRequest,
    1839           0 :                                   nsDependentString(kSuccessEventType),
    1840           0 :                                   aResponse.previousVersion());
    1841           0 :   MOZ_ASSERT(successEvent);
    1842             : 
    1843           0 :   DispatchSuccessEvent(&helper, successEvent);
    1844             : 
    1845           0 :   return true;
    1846             : }
    1847             : 
    1848             : void
    1849           0 : BackgroundFactoryRequestChild::ActorDestroy(ActorDestroyReason aWhy)
    1850             : {
    1851           0 :   AssertIsOnOwningThread();
    1852             : 
    1853           0 :   MaybeCollectGarbageOnIPCMessage();
    1854             : 
    1855           0 :   if (aWhy != Deletion) {
    1856           0 :     IDBOpenDBRequest* openRequest = GetOpenDBRequest();
    1857           0 :     if (openRequest) {
    1858           0 :       openRequest->NoteComplete();
    1859             :     }
    1860             :   }
    1861           0 : }
    1862             : 
    1863             : mozilla::ipc::IPCResult
    1864           0 : BackgroundFactoryRequestChild::Recv__delete__(
    1865             :                                         const FactoryRequestResponse& aResponse)
    1866             : {
    1867           0 :   AssertIsOnOwningThread();
    1868           0 :   MOZ_ASSERT(mRequest);
    1869             : 
    1870           0 :   MaybeCollectGarbageOnIPCMessage();
    1871             : 
    1872             :   bool result;
    1873             : 
    1874           0 :   switch (aResponse.type()) {
    1875             :     case FactoryRequestResponse::Tnsresult:
    1876           0 :       result = HandleResponse(aResponse.get_nsresult());
    1877           0 :       break;
    1878             : 
    1879             :     case FactoryRequestResponse::TOpenDatabaseRequestResponse:
    1880           0 :       result = HandleResponse(aResponse.get_OpenDatabaseRequestResponse());
    1881           0 :       break;
    1882             : 
    1883             :     case FactoryRequestResponse::TDeleteDatabaseRequestResponse:
    1884           0 :       result = HandleResponse(aResponse.get_DeleteDatabaseRequestResponse());
    1885           0 :       break;
    1886             : 
    1887             :     default:
    1888           0 :       MOZ_CRASH("Unknown response type!");
    1889             :   }
    1890             : 
    1891           0 :   IDBOpenDBRequest* request = GetOpenDBRequest();
    1892           0 :   MOZ_ASSERT(request);
    1893             : 
    1894           0 :   request->NoteComplete();
    1895             : 
    1896           0 :   if (NS_WARN_IF(!result)) {
    1897           0 :     return IPC_FAIL_NO_REASON(this);
    1898             :   }
    1899             : 
    1900           0 :   return IPC_OK();
    1901             : }
    1902             : 
    1903             : mozilla::ipc::IPCResult
    1904           0 : BackgroundFactoryRequestChild::RecvPermissionChallenge(
    1905             :                                             const PrincipalInfo& aPrincipalInfo)
    1906             : {
    1907           0 :   AssertIsOnOwningThread();
    1908             : 
    1909           0 :   MaybeCollectGarbageOnIPCMessage();
    1910             : 
    1911           0 :   if (!NS_IsMainThread()) {
    1912           0 :     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
    1913           0 :     MOZ_ASSERT(workerPrivate);
    1914           0 :     workerPrivate->AssertIsOnWorkerThread();
    1915             : 
    1916             :     RefPtr<WorkerPermissionChallenge> challenge =
    1917             :       new WorkerPermissionChallenge(workerPrivate, this, mFactory,
    1918           0 :                                     aPrincipalInfo);
    1919           0 :     if (!challenge->Dispatch()) {
    1920           0 :       return IPC_FAIL_NO_REASON(this);
    1921             :     }
    1922           0 :     return IPC_OK();
    1923             :   }
    1924             : 
    1925             :   nsresult rv;
    1926             :   nsCOMPtr<nsIPrincipal> principal =
    1927           0 :     mozilla::ipc::PrincipalInfoToPrincipal(aPrincipalInfo, &rv);
    1928           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    1929           0 :     return IPC_FAIL_NO_REASON(this);
    1930             :   }
    1931             : 
    1932           0 :   if (XRE_IsParentProcess()) {
    1933           0 :     nsCOMPtr<nsPIDOMWindowInner> window = mFactory->GetParentObject();
    1934           0 :     MOZ_ASSERT(window);
    1935             : 
    1936             :     nsCOMPtr<Element> ownerElement =
    1937           0 :       do_QueryInterface(window->GetChromeEventHandler());
    1938           0 :     if (NS_WARN_IF(!ownerElement)) {
    1939             :       // If this fails, the page was navigated. Fail the permission check by
    1940             :       // forcing an immediate retry.
    1941           0 :       if (!SendPermissionRetry()) {
    1942           0 :         return IPC_FAIL_NO_REASON(this);
    1943             :       }
    1944           0 :       return IPC_OK();
    1945             :     }
    1946             : 
    1947             :     RefPtr<PermissionRequestMainProcessHelper> helper =
    1948           0 :       new PermissionRequestMainProcessHelper(this, mFactory, ownerElement, principal);
    1949             : 
    1950             :     PermissionRequestBase::PermissionValue permission;
    1951           0 :     if (NS_WARN_IF(NS_FAILED(helper->PromptIfNeeded(&permission)))) {
    1952           0 :       return IPC_FAIL_NO_REASON(this);
    1953             :     }
    1954             : 
    1955           0 :     MOZ_ASSERT(permission == PermissionRequestBase::kPermissionAllowed ||
    1956             :                permission == PermissionRequestBase::kPermissionDenied ||
    1957             :                permission == PermissionRequestBase::kPermissionPrompt);
    1958             : 
    1959           0 :     if (permission != PermissionRequestBase::kPermissionPrompt) {
    1960           0 :       SendPermissionRetry();
    1961             :     }
    1962           0 :     return IPC_OK();
    1963             :   }
    1964             : 
    1965           0 :   RefPtr<TabChild> tabChild = mFactory->GetTabChild();
    1966           0 :   MOZ_ASSERT(tabChild);
    1967             : 
    1968           0 :   IPC::Principal ipcPrincipal(principal);
    1969             : 
    1970           0 :   auto* actor = new PermissionRequestChildProcessActor(this, mFactory);
    1971             : 
    1972           0 :   tabChild->SetEventTargetForActor(actor, this->GetActorEventTarget());
    1973           0 :   MOZ_ASSERT(actor->GetActorEventTarget());
    1974           0 :   tabChild->SendPIndexedDBPermissionRequestConstructor(actor, ipcPrincipal);
    1975             : 
    1976           0 :   return IPC_OK();
    1977             : }
    1978             : 
    1979             : mozilla::ipc::IPCResult
    1980           0 : BackgroundFactoryRequestChild::RecvBlocked(const uint64_t& aCurrentVersion)
    1981             : {
    1982           0 :   AssertIsOnOwningThread();
    1983           0 :   MOZ_ASSERT(mRequest);
    1984             : 
    1985           0 :   MaybeCollectGarbageOnIPCMessage();
    1986             : 
    1987           0 :   const nsDependentString type(kBlockedEventType);
    1988             : 
    1989           0 :   nsCOMPtr<nsIDOMEvent> blockedEvent;
    1990           0 :   if (mIsDeleteOp) {
    1991             :     blockedEvent =
    1992           0 :       IDBVersionChangeEvent::Create(mRequest, type, aCurrentVersion);
    1993           0 :     MOZ_ASSERT(blockedEvent);
    1994             :   } else {
    1995             :     blockedEvent =
    1996           0 :       IDBVersionChangeEvent::Create(mRequest,
    1997             :                                     type,
    1998             :                                     aCurrentVersion,
    1999           0 :                                     mRequestedVersion);
    2000           0 :     MOZ_ASSERT(blockedEvent);
    2001             :   }
    2002             : 
    2003           0 :   RefPtr<IDBRequest> kungFuDeathGrip = mRequest;
    2004             : 
    2005           0 :   IDB_LOG_MARK("IndexedDB %s: Child  Request[%llu]: Firing \"blocked\" event",
    2006             :                "IndexedDB %s: C R[%llu]: \"blocked\"",
    2007             :                IDB_LOG_ID_STRING(),
    2008             :                kungFuDeathGrip->LoggingSerialNumber());
    2009             : 
    2010             :   bool dummy;
    2011           0 :   if (NS_FAILED(kungFuDeathGrip->DispatchEvent(blockedEvent, &dummy))) {
    2012           0 :     NS_WARNING("Failed to dispatch event!");
    2013             :   }
    2014             : 
    2015           0 :   return IPC_OK();
    2016             : }
    2017             : 
    2018             : /*******************************************************************************
    2019             :  * BackgroundDatabaseChild
    2020             :  ******************************************************************************/
    2021             : 
    2022           0 : BackgroundDatabaseChild::BackgroundDatabaseChild(
    2023             :                                const DatabaseSpec& aSpec,
    2024           0 :                                BackgroundFactoryRequestChild* aOpenRequestActor)
    2025           0 :   : mSpec(new DatabaseSpec(aSpec))
    2026             :   , mOpenRequestActor(aOpenRequestActor)
    2027           0 :   , mDatabase(nullptr)
    2028             : {
    2029             :   // Can't assert owning thread here because IPDL has not yet set our manager!
    2030           0 :   MOZ_ASSERT(aOpenRequestActor);
    2031             : 
    2032           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundDatabaseChild);
    2033           0 : }
    2034             : 
    2035           0 : BackgroundDatabaseChild::~BackgroundDatabaseChild()
    2036             : {
    2037           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundDatabaseChild);
    2038           0 : }
    2039             : 
    2040             : #ifdef DEBUG
    2041             : 
    2042             : void
    2043           0 : BackgroundDatabaseChild::AssertIsOnOwningThread() const
    2044             : {
    2045           0 :   static_cast<BackgroundFactoryChild*>(Manager())->AssertIsOnOwningThread();
    2046           0 : }
    2047             : 
    2048             : #endif // DEBUG
    2049             : 
    2050             : void
    2051           0 : BackgroundDatabaseChild::SendDeleteMeInternal()
    2052             : {
    2053           0 :   AssertIsOnOwningThread();
    2054           0 :   MOZ_ASSERT(!mTemporaryStrongDatabase);
    2055           0 :   MOZ_ASSERT(!mOpenRequestActor);
    2056             : 
    2057           0 :   if (mDatabase) {
    2058           0 :     mDatabase->ClearBackgroundActor();
    2059           0 :     mDatabase = nullptr;
    2060             : 
    2061           0 :     MOZ_ALWAYS_TRUE(PBackgroundIDBDatabaseChild::SendDeleteMe());
    2062             :   }
    2063           0 : }
    2064             : 
    2065             : void
    2066           0 : BackgroundDatabaseChild::EnsureDOMObject()
    2067             : {
    2068           0 :   AssertIsOnOwningThread();
    2069           0 :   MOZ_ASSERT(mOpenRequestActor);
    2070             : 
    2071           0 :   if (mTemporaryStrongDatabase) {
    2072           0 :     MOZ_ASSERT(!mSpec);
    2073           0 :     return;
    2074             :   }
    2075             : 
    2076           0 :   MOZ_ASSERT(mSpec);
    2077             : 
    2078           0 :   auto request = mOpenRequestActor->GetOpenDBRequest();
    2079           0 :   MOZ_ASSERT(request);
    2080             : 
    2081             :   auto factory =
    2082           0 :     static_cast<BackgroundFactoryChild*>(Manager())->GetDOMObject();
    2083           0 :   MOZ_ASSERT(factory);
    2084             : 
    2085             :   mTemporaryStrongDatabase =
    2086           0 :     IDBDatabase::Create(request, factory, this, mSpec);
    2087             : 
    2088           0 :   MOZ_ASSERT(mTemporaryStrongDatabase);
    2089           0 :   mTemporaryStrongDatabase->AssertIsOnOwningThread();
    2090             : 
    2091           0 :   mDatabase = mTemporaryStrongDatabase;
    2092           0 :   mSpec.forget();
    2093             : }
    2094             : 
    2095             : void
    2096           0 : BackgroundDatabaseChild::ReleaseDOMObject()
    2097             : {
    2098           0 :   AssertIsOnOwningThread();
    2099           0 :   MOZ_ASSERT(mTemporaryStrongDatabase);
    2100           0 :   mTemporaryStrongDatabase->AssertIsOnOwningThread();
    2101           0 :   MOZ_ASSERT(mOpenRequestActor);
    2102           0 :   MOZ_ASSERT(mDatabase == mTemporaryStrongDatabase);
    2103             : 
    2104           0 :   mOpenRequestActor = nullptr;
    2105             : 
    2106             :   // This may be the final reference to the IDBDatabase object so we may end up
    2107             :   // calling SendDeleteMeInternal() here. Make sure everything is cleaned up
    2108             :   // properly before proceeding.
    2109           0 :   mTemporaryStrongDatabase = nullptr;
    2110           0 : }
    2111             : 
    2112             : void
    2113           0 : BackgroundDatabaseChild::ActorDestroy(ActorDestroyReason aWhy)
    2114             : {
    2115           0 :   AssertIsOnOwningThread();
    2116             : 
    2117           0 :   MaybeCollectGarbageOnIPCMessage();
    2118             : 
    2119           0 :   if (mDatabase) {
    2120           0 :     mDatabase->ClearBackgroundActor();
    2121             : #ifdef DEBUG
    2122           0 :     mDatabase = nullptr;
    2123             : #endif
    2124             :   }
    2125           0 : }
    2126             : 
    2127             : PBackgroundIDBDatabaseFileChild*
    2128           0 : BackgroundDatabaseChild::AllocPBackgroundIDBDatabaseFileChild(
    2129             :                                                         const IPCBlob& aIPCBlob)
    2130             : {
    2131           0 :   MOZ_CRASH("PBackgroundIDBFileChild actors should be manually constructed!");
    2132             : }
    2133             : 
    2134             : bool
    2135           0 : BackgroundDatabaseChild::DeallocPBackgroundIDBDatabaseFileChild(
    2136             :                                         PBackgroundIDBDatabaseFileChild* aActor)
    2137             : {
    2138           0 :   AssertIsOnOwningThread();
    2139           0 :   MOZ_ASSERT(aActor);
    2140             : 
    2141           0 :   delete aActor;
    2142           0 :   return true;
    2143             : }
    2144             : 
    2145             : PBackgroundIDBDatabaseRequestChild*
    2146           0 : BackgroundDatabaseChild::AllocPBackgroundIDBDatabaseRequestChild(
    2147             :                                            const DatabaseRequestParams& aParams)
    2148             : {
    2149           0 :   MOZ_CRASH("PBackgroundIDBDatabaseRequestChild actors should be manually "
    2150             :             "constructed!");
    2151             : }
    2152             : 
    2153             : bool
    2154           0 : BackgroundDatabaseChild::DeallocPBackgroundIDBDatabaseRequestChild(
    2155             :                                      PBackgroundIDBDatabaseRequestChild* aActor)
    2156             : {
    2157           0 :   MOZ_ASSERT(aActor);
    2158             : 
    2159           0 :   delete static_cast<BackgroundDatabaseRequestChild*>(aActor);
    2160           0 :   return true;
    2161             : }
    2162             : 
    2163             : PBackgroundIDBTransactionChild*
    2164           0 : BackgroundDatabaseChild::AllocPBackgroundIDBTransactionChild(
    2165             :                                     const nsTArray<nsString>& aObjectStoreNames,
    2166             :                                     const Mode& aMode)
    2167             : {
    2168           0 :   MOZ_CRASH("PBackgroundIDBTransactionChild actors should be manually "
    2169             :             "constructed!");
    2170             : }
    2171             : 
    2172             : bool
    2173           0 : BackgroundDatabaseChild::DeallocPBackgroundIDBTransactionChild(
    2174             :                                          PBackgroundIDBTransactionChild* aActor)
    2175             : {
    2176           0 :   MOZ_ASSERT(aActor);
    2177             : 
    2178           0 :   delete static_cast<BackgroundTransactionChild*>(aActor);
    2179           0 :   return true;
    2180             : }
    2181             : 
    2182             : PBackgroundIDBVersionChangeTransactionChild*
    2183           0 : BackgroundDatabaseChild::AllocPBackgroundIDBVersionChangeTransactionChild(
    2184             :                                               const uint64_t& aCurrentVersion,
    2185             :                                               const uint64_t& aRequestedVersion,
    2186             :                                               const int64_t& aNextObjectStoreId,
    2187             :                                               const int64_t& aNextIndexId)
    2188             : {
    2189           0 :   AssertIsOnOwningThread();
    2190             : 
    2191           0 :   IDBOpenDBRequest* request = mOpenRequestActor->GetOpenDBRequest();
    2192           0 :   MOZ_ASSERT(request);
    2193             : 
    2194           0 :   return new BackgroundVersionChangeTransactionChild(request);
    2195             : }
    2196             : 
    2197             : mozilla::ipc::IPCResult
    2198           0 : BackgroundDatabaseChild::RecvPBackgroundIDBVersionChangeTransactionConstructor(
    2199             :                             PBackgroundIDBVersionChangeTransactionChild* aActor,
    2200             :                             const uint64_t& aCurrentVersion,
    2201             :                             const uint64_t& aRequestedVersion,
    2202             :                             const int64_t& aNextObjectStoreId,
    2203             :                             const int64_t& aNextIndexId)
    2204             : {
    2205           0 :   AssertIsOnOwningThread();
    2206           0 :   MOZ_ASSERT(aActor);
    2207           0 :   MOZ_ASSERT(aActor->GetActorEventTarget(),
    2208             :     "The event target shall be inherited from its manager actor.");
    2209           0 :   MOZ_ASSERT(mOpenRequestActor);
    2210             : 
    2211           0 :   MaybeCollectGarbageOnIPCMessage();
    2212             : 
    2213           0 :   EnsureDOMObject();
    2214             : 
    2215           0 :   auto* actor = static_cast<BackgroundVersionChangeTransactionChild*>(aActor);
    2216             : 
    2217           0 :   RefPtr<IDBOpenDBRequest> request = mOpenRequestActor->GetOpenDBRequest();
    2218           0 :   MOZ_ASSERT(request);
    2219             : 
    2220             :   RefPtr<IDBTransaction> transaction =
    2221           0 :     IDBTransaction::CreateVersionChange(mDatabase,
    2222             :                                         actor,
    2223             :                                         request,
    2224             :                                         aNextObjectStoreId,
    2225           0 :                                         aNextIndexId);
    2226           0 :   MOZ_ASSERT(transaction);
    2227             : 
    2228           0 :   transaction->AssertIsOnOwningThread();
    2229             : 
    2230           0 :   actor->SetDOMTransaction(transaction);
    2231             : 
    2232           0 :   mDatabase->EnterSetVersionTransaction(aRequestedVersion);
    2233             : 
    2234           0 :   request->SetTransaction(transaction);
    2235             : 
    2236             :   nsCOMPtr<nsIDOMEvent> upgradeNeededEvent =
    2237           0 :     IDBVersionChangeEvent::Create(request,
    2238           0 :                                   nsDependentString(kUpgradeNeededEventType),
    2239             :                                   aCurrentVersion,
    2240           0 :                                   aRequestedVersion);
    2241           0 :   MOZ_ASSERT(upgradeNeededEvent);
    2242             : 
    2243           0 :   ResultHelper helper(request, transaction, mDatabase);
    2244             : 
    2245           0 :   DispatchSuccessEvent(&helper, upgradeNeededEvent);
    2246             : 
    2247           0 :   return IPC_OK();
    2248             : }
    2249             : 
    2250             : bool
    2251           0 : BackgroundDatabaseChild::DeallocPBackgroundIDBVersionChangeTransactionChild(
    2252             :                             PBackgroundIDBVersionChangeTransactionChild* aActor)
    2253             : {
    2254           0 :   MOZ_ASSERT(aActor);
    2255             : 
    2256           0 :   delete static_cast<BackgroundVersionChangeTransactionChild*>(aActor);
    2257           0 :   return true;
    2258             : }
    2259             : 
    2260             : PBackgroundMutableFileChild*
    2261           0 : BackgroundDatabaseChild::AllocPBackgroundMutableFileChild(const nsString& aName,
    2262             :                                                           const nsString& aType)
    2263             : {
    2264           0 :   AssertIsOnOwningThread();
    2265             : 
    2266           0 :   return new BackgroundMutableFileChild(aName, aType);
    2267             : }
    2268             : 
    2269             : bool
    2270           0 : BackgroundDatabaseChild::DeallocPBackgroundMutableFileChild(
    2271             :                                             PBackgroundMutableFileChild* aActor)
    2272             : {
    2273           0 :   MOZ_ASSERT(aActor);
    2274             : 
    2275           0 :   delete static_cast<BackgroundMutableFileChild*>(aActor);
    2276           0 :   return true;
    2277             : }
    2278             : 
    2279             : mozilla::ipc::IPCResult
    2280           0 : BackgroundDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion,
    2281             :                                            const NullableVersion& aNewVersion)
    2282             : {
    2283           0 :   AssertIsOnOwningThread();
    2284             : 
    2285           0 :   MaybeCollectGarbageOnIPCMessage();
    2286             : 
    2287           0 :   if (!mDatabase || mDatabase->IsClosed()) {
    2288           0 :     return IPC_OK();
    2289             :   }
    2290             : 
    2291           0 :   RefPtr<IDBDatabase> kungFuDeathGrip = mDatabase;
    2292             : 
    2293             :   // Handle bfcache'd windows.
    2294           0 :   if (nsPIDOMWindowInner* owner = kungFuDeathGrip->GetOwner()) {
    2295             :     // The database must be closed if the window is already frozen.
    2296           0 :     bool shouldAbortAndClose = owner->IsFrozen();
    2297             : 
    2298             :     // Anything in the bfcache has to be evicted and then we have to close the
    2299             :     // database also.
    2300           0 :     if (nsCOMPtr<nsIDocument> doc = owner->GetExtantDoc()) {
    2301           0 :       if (nsCOMPtr<nsIBFCacheEntry> bfCacheEntry = doc->GetBFCacheEntry()) {
    2302           0 :         bfCacheEntry->RemoveFromBFCacheSync();
    2303           0 :         shouldAbortAndClose = true;
    2304             :       }
    2305             :     }
    2306             : 
    2307           0 :     if (shouldAbortAndClose) {
    2308             :       // Invalidate() doesn't close the database in the parent, so we have
    2309             :       // to call Close() and AbortTransactions() manually.
    2310           0 :       kungFuDeathGrip->AbortTransactions(/* aShouldWarn */ false);
    2311           0 :       kungFuDeathGrip->Close();
    2312           0 :       return IPC_OK();
    2313             :     }
    2314             :   }
    2315             : 
    2316             :   // Otherwise fire a versionchange event.
    2317           0 :   const nsDependentString type(kVersionChangeEventType);
    2318             : 
    2319           0 :   nsCOMPtr<nsIDOMEvent> versionChangeEvent;
    2320             : 
    2321           0 :   switch (aNewVersion.type()) {
    2322             :     case NullableVersion::Tnull_t:
    2323             :       versionChangeEvent =
    2324           0 :         IDBVersionChangeEvent::Create(kungFuDeathGrip, type, aOldVersion);
    2325           0 :       MOZ_ASSERT(versionChangeEvent);
    2326           0 :       break;
    2327             : 
    2328             :     case NullableVersion::Tuint64_t:
    2329             :       versionChangeEvent =
    2330           0 :         IDBVersionChangeEvent::Create(kungFuDeathGrip,
    2331             :                                       type,
    2332             :                                       aOldVersion,
    2333           0 :                                       aNewVersion.get_uint64_t());
    2334           0 :       MOZ_ASSERT(versionChangeEvent);
    2335           0 :       break;
    2336             : 
    2337             :     default:
    2338           0 :       MOZ_CRASH("Should never get here!");
    2339             :   }
    2340             : 
    2341           0 :   IDB_LOG_MARK("IndexedDB %s: Child : Firing \"versionchange\" event",
    2342             :                "IndexedDB %s: C: IDBDatabase \"versionchange\" event",
    2343             :                IDB_LOG_ID_STRING());
    2344             : 
    2345             :   bool dummy;
    2346           0 :   if (NS_FAILED(kungFuDeathGrip->DispatchEvent(versionChangeEvent, &dummy))) {
    2347           0 :     NS_WARNING("Failed to dispatch event!");
    2348             :   }
    2349             : 
    2350           0 :   if (!kungFuDeathGrip->IsClosed()) {
    2351           0 :     SendBlocked();
    2352             :   }
    2353             : 
    2354           0 :   return IPC_OK();
    2355             : }
    2356             : 
    2357             : mozilla::ipc::IPCResult
    2358           0 : BackgroundDatabaseChild::RecvInvalidate()
    2359             : {
    2360           0 :   AssertIsOnOwningThread();
    2361             : 
    2362           0 :   MaybeCollectGarbageOnIPCMessage();
    2363             : 
    2364           0 :   if (mDatabase) {
    2365           0 :     mDatabase->Invalidate();
    2366             :   }
    2367             : 
    2368           0 :   return IPC_OK();
    2369             : }
    2370             : 
    2371             : mozilla::ipc::IPCResult
    2372           0 : BackgroundDatabaseChild::RecvCloseAfterInvalidationComplete()
    2373             : {
    2374           0 :   AssertIsOnOwningThread();
    2375             : 
    2376           0 :   MaybeCollectGarbageOnIPCMessage();
    2377             : 
    2378           0 :   if (mDatabase) {
    2379           0 :     mDatabase->DispatchTrustedEvent(nsDependentString(kCloseEventType));
    2380             :   }
    2381             : 
    2382           0 :   return IPC_OK();
    2383             : }
    2384             : 
    2385             : /*******************************************************************************
    2386             :  * BackgroundDatabaseRequestChild
    2387             :  ******************************************************************************/
    2388             : 
    2389           0 : BackgroundDatabaseRequestChild::BackgroundDatabaseRequestChild(
    2390             :                                                          IDBDatabase* aDatabase,
    2391           0 :                                                          IDBRequest* aRequest)
    2392             :   : BackgroundRequestChildBase(aRequest)
    2393           0 :   , mDatabase(aDatabase)
    2394             : {
    2395             :   // Can't assert owning thread here because IPDL has not yet set our manager!
    2396           0 :   MOZ_ASSERT(aDatabase);
    2397           0 :   aDatabase->AssertIsOnOwningThread();
    2398           0 :   MOZ_ASSERT(aRequest);
    2399             : 
    2400           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundDatabaseRequestChild);
    2401           0 : }
    2402             : 
    2403           0 : BackgroundDatabaseRequestChild::~BackgroundDatabaseRequestChild()
    2404             : {
    2405           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundDatabaseRequestChild);
    2406           0 : }
    2407             : 
    2408             : bool
    2409           0 : BackgroundDatabaseRequestChild::HandleResponse(nsresult aResponse)
    2410             : {
    2411           0 :   AssertIsOnOwningThread();
    2412           0 :   MOZ_ASSERT(NS_FAILED(aResponse));
    2413           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aResponse) == NS_ERROR_MODULE_DOM_INDEXEDDB);
    2414             : 
    2415           0 :   mRequest->Reset();
    2416             : 
    2417           0 :   DispatchErrorEvent(mRequest, aResponse);
    2418             : 
    2419           0 :   return true;
    2420             : }
    2421             : 
    2422             : bool
    2423           0 : BackgroundDatabaseRequestChild::HandleResponse(
    2424             :                                      const CreateFileRequestResponse& aResponse)
    2425             : {
    2426           0 :   AssertIsOnOwningThread();
    2427             : 
    2428           0 :   mRequest->Reset();
    2429             : 
    2430             :   auto mutableFileActor =
    2431           0 :     static_cast<BackgroundMutableFileChild*>(aResponse.mutableFileChild());
    2432           0 :   MOZ_ASSERT(mutableFileActor);
    2433             : 
    2434           0 :   mutableFileActor->EnsureDOMObject();
    2435             : 
    2436             :   auto mutableFile =
    2437           0 :     static_cast<IDBMutableFile*>(mutableFileActor->GetDOMObject());
    2438           0 :   MOZ_ASSERT(mutableFile);
    2439             : 
    2440           0 :   ResultHelper helper(mRequest, nullptr, mutableFile);
    2441             : 
    2442           0 :   DispatchSuccessEvent(&helper);
    2443             : 
    2444           0 :   mutableFileActor->ReleaseDOMObject();
    2445             : 
    2446           0 :   return true;
    2447             : }
    2448             : 
    2449             : mozilla::ipc::IPCResult
    2450           0 : BackgroundDatabaseRequestChild::Recv__delete__(
    2451             :                                        const DatabaseRequestResponse& aResponse)
    2452             : {
    2453           0 :   AssertIsOnOwningThread();
    2454           0 :   MOZ_ASSERT(mRequest);
    2455             : 
    2456           0 :   switch (aResponse.type()) {
    2457             :     case DatabaseRequestResponse::Tnsresult:
    2458           0 :       if (!HandleResponse(aResponse.get_nsresult())) {
    2459           0 :         return IPC_FAIL_NO_REASON(this);
    2460             :       }
    2461           0 :       return IPC_OK();
    2462             : 
    2463             :     case DatabaseRequestResponse::TCreateFileRequestResponse:
    2464           0 :       if (!HandleResponse(aResponse.get_CreateFileRequestResponse())) {
    2465           0 :         return IPC_FAIL_NO_REASON(this);
    2466             :       }
    2467           0 :       return IPC_OK();
    2468             : 
    2469             :     default:
    2470           0 :       MOZ_CRASH("Unknown response type!");
    2471             :   }
    2472             : 
    2473             :   MOZ_CRASH("Should never get here!");
    2474             : }
    2475             : 
    2476             : /*******************************************************************************
    2477             :  * BackgroundTransactionBase
    2478             :  ******************************************************************************/
    2479             : 
    2480           0 : BackgroundTransactionBase::BackgroundTransactionBase()
    2481           0 : : mTransaction(nullptr)
    2482             : {
    2483           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundTransactionBase);
    2484           0 : }
    2485             : 
    2486           0 : BackgroundTransactionBase::BackgroundTransactionBase(
    2487           0 :                                                    IDBTransaction* aTransaction)
    2488             :   : mTemporaryStrongTransaction(aTransaction)
    2489           0 :   , mTransaction(aTransaction)
    2490             : {
    2491           0 :   MOZ_ASSERT(aTransaction);
    2492           0 :   aTransaction->AssertIsOnOwningThread();
    2493             : 
    2494           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundTransactionBase);
    2495           0 : }
    2496             : 
    2497           0 : BackgroundTransactionBase::~BackgroundTransactionBase()
    2498             : {
    2499           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundTransactionBase);
    2500           0 : }
    2501             : 
    2502             : #ifdef DEBUG
    2503             : 
    2504             : void
    2505           0 : BackgroundTransactionBase::AssertIsOnOwningThread() const
    2506             : {
    2507           0 :   MOZ_ASSERT(mTransaction);
    2508           0 :   mTransaction->AssertIsOnOwningThread();
    2509           0 : }
    2510             : 
    2511             : #endif // DEBUG
    2512             : 
    2513             : void
    2514           0 : BackgroundTransactionBase::NoteActorDestroyed()
    2515             : {
    2516           0 :   AssertIsOnOwningThread();
    2517           0 :   MOZ_ASSERT_IF(mTemporaryStrongTransaction, mTransaction);
    2518             : 
    2519           0 :   if (mTransaction) {
    2520           0 :     mTransaction->ClearBackgroundActor();
    2521             : 
    2522             :     // Normally this would be DEBUG-only but NoteActorDestroyed is also called
    2523             :     // from SendDeleteMeInternal. In that case we're going to receive an actual
    2524             :     // ActorDestroy call later and we don't want to touch a dead object.
    2525           0 :     mTemporaryStrongTransaction = nullptr;
    2526           0 :     mTransaction = nullptr;
    2527             :   }
    2528           0 : }
    2529             : 
    2530             : void
    2531           0 : BackgroundTransactionBase::SetDOMTransaction(IDBTransaction* aTransaction)
    2532             : {
    2533           0 :   AssertIsOnOwningThread();
    2534           0 :   MOZ_ASSERT(aTransaction);
    2535           0 :   aTransaction->AssertIsOnOwningThread();
    2536           0 :   MOZ_ASSERT(!mTemporaryStrongTransaction);
    2537           0 :   MOZ_ASSERT(!mTransaction);
    2538             : 
    2539           0 :   mTemporaryStrongTransaction = aTransaction;
    2540           0 :   mTransaction = aTransaction;
    2541           0 : }
    2542             : 
    2543             : void
    2544           0 : BackgroundTransactionBase::NoteComplete()
    2545             : {
    2546           0 :   AssertIsOnOwningThread();
    2547           0 :   MOZ_ASSERT_IF(mTransaction, mTemporaryStrongTransaction);
    2548             : 
    2549           0 :   mTemporaryStrongTransaction = nullptr;
    2550           0 : }
    2551             : 
    2552             : /*******************************************************************************
    2553             :  * BackgroundTransactionChild
    2554             :  ******************************************************************************/
    2555             : 
    2556           0 : BackgroundTransactionChild::BackgroundTransactionChild(
    2557           0 :                                                    IDBTransaction* aTransaction)
    2558           0 :   : BackgroundTransactionBase(aTransaction)
    2559             : {
    2560           0 :   MOZ_ASSERT(aTransaction);
    2561           0 :   aTransaction->AssertIsOnOwningThread();
    2562             : 
    2563           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundTransactionChild);
    2564           0 : }
    2565             : 
    2566           0 : BackgroundTransactionChild::~BackgroundTransactionChild()
    2567             : {
    2568           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundTransactionChild);
    2569           0 : }
    2570             : 
    2571             : #ifdef DEBUG
    2572             : 
    2573             : void
    2574           0 : BackgroundTransactionChild::AssertIsOnOwningThread() const
    2575             : {
    2576           0 :   static_cast<BackgroundDatabaseChild*>(Manager())->AssertIsOnOwningThread();
    2577           0 : }
    2578             : 
    2579             : #endif // DEBUG
    2580             : 
    2581             : void
    2582           0 : BackgroundTransactionChild::SendDeleteMeInternal()
    2583             : {
    2584           0 :   AssertIsOnOwningThread();
    2585             : 
    2586           0 :   if (mTransaction) {
    2587           0 :     NoteActorDestroyed();
    2588             : 
    2589           0 :     MOZ_ALWAYS_TRUE(PBackgroundIDBTransactionChild::SendDeleteMe());
    2590             :   }
    2591           0 : }
    2592             : 
    2593             : void
    2594           0 : BackgroundTransactionChild::ActorDestroy(ActorDestroyReason aWhy)
    2595             : {
    2596           0 :   AssertIsOnOwningThread();
    2597             : 
    2598           0 :   MaybeCollectGarbageOnIPCMessage();
    2599             : 
    2600           0 :   NoteActorDestroyed();
    2601           0 : }
    2602             : 
    2603             : mozilla::ipc::IPCResult
    2604           0 : BackgroundTransactionChild::RecvComplete(const nsresult& aResult)
    2605             : {
    2606           0 :   AssertIsOnOwningThread();
    2607           0 :   MOZ_ASSERT(mTransaction);
    2608             : 
    2609           0 :   MaybeCollectGarbageOnIPCMessage();
    2610             : 
    2611           0 :   mTransaction->FireCompleteOrAbortEvents(aResult);
    2612             : 
    2613           0 :   NoteComplete();
    2614           0 :   return IPC_OK();
    2615             : }
    2616             : 
    2617             : PBackgroundIDBRequestChild*
    2618           0 : BackgroundTransactionChild::AllocPBackgroundIDBRequestChild(
    2619             :                                                    const RequestParams& aParams)
    2620             : {
    2621           0 :   MOZ_CRASH("PBackgroundIDBRequestChild actors should be manually "
    2622             :             "constructed!");
    2623             : }
    2624             : 
    2625             : bool
    2626           0 : BackgroundTransactionChild::DeallocPBackgroundIDBRequestChild(
    2627             :                                              PBackgroundIDBRequestChild* aActor)
    2628             : {
    2629           0 :   MOZ_ASSERT(aActor);
    2630             : 
    2631           0 :   delete static_cast<BackgroundRequestChild*>(aActor);
    2632           0 :   return true;
    2633             : }
    2634             : 
    2635             : PBackgroundIDBCursorChild*
    2636           0 : BackgroundTransactionChild::AllocPBackgroundIDBCursorChild(
    2637             :                                                 const OpenCursorParams& aParams)
    2638             : {
    2639           0 :   AssertIsOnOwningThread();
    2640             : 
    2641           0 :   MOZ_CRASH("PBackgroundIDBCursorChild actors should be manually constructed!");
    2642             : }
    2643             : 
    2644             : bool
    2645           0 : BackgroundTransactionChild::DeallocPBackgroundIDBCursorChild(
    2646             :                                               PBackgroundIDBCursorChild* aActor)
    2647             : {
    2648           0 :   MOZ_ASSERT(aActor);
    2649             : 
    2650           0 :   delete static_cast<BackgroundCursorChild*>(aActor);
    2651           0 :   return true;
    2652             : }
    2653             : 
    2654             : /*******************************************************************************
    2655             :  * BackgroundVersionChangeTransactionChild
    2656             :  ******************************************************************************/
    2657             : 
    2658           0 : BackgroundVersionChangeTransactionChild::
    2659           0 : BackgroundVersionChangeTransactionChild(IDBOpenDBRequest* aOpenDBRequest)
    2660           0 :   : mOpenDBRequest(aOpenDBRequest)
    2661             : {
    2662           0 :   MOZ_ASSERT(aOpenDBRequest);
    2663           0 :   aOpenDBRequest->AssertIsOnOwningThread();
    2664             : 
    2665           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundVersionChangeTransactionChild);
    2666           0 : }
    2667             : 
    2668           0 : BackgroundVersionChangeTransactionChild::
    2669           0 : ~BackgroundVersionChangeTransactionChild()
    2670             : {
    2671           0 :   AssertIsOnOwningThread();
    2672             : 
    2673           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundVersionChangeTransactionChild);
    2674           0 : }
    2675             : 
    2676             : #ifdef DEBUG
    2677             : 
    2678             : void
    2679           0 : BackgroundVersionChangeTransactionChild::AssertIsOnOwningThread() const
    2680             : {
    2681           0 :   static_cast<BackgroundDatabaseChild*>(Manager())->AssertIsOnOwningThread();
    2682           0 : }
    2683             : 
    2684             : #endif // DEBUG
    2685             : 
    2686             : void
    2687           0 : BackgroundVersionChangeTransactionChild::SendDeleteMeInternal(
    2688             :                                                         bool aFailedConstructor)
    2689             : {
    2690           0 :   AssertIsOnOwningThread();
    2691             : 
    2692           0 :   if (mTransaction || aFailedConstructor) {
    2693           0 :     NoteActorDestroyed();
    2694             : 
    2695           0 :     MOZ_ALWAYS_TRUE(PBackgroundIDBVersionChangeTransactionChild::
    2696             :                       SendDeleteMe());
    2697             :   }
    2698           0 : }
    2699             : 
    2700             : void
    2701           0 : BackgroundVersionChangeTransactionChild::ActorDestroy(ActorDestroyReason aWhy)
    2702             : {
    2703           0 :   AssertIsOnOwningThread();
    2704             : 
    2705           0 :   MaybeCollectGarbageOnIPCMessage();
    2706             : 
    2707           0 :   mOpenDBRequest = nullptr;
    2708             : 
    2709           0 :   NoteActorDestroyed();
    2710           0 : }
    2711             : 
    2712             : mozilla::ipc::IPCResult
    2713           0 : BackgroundVersionChangeTransactionChild::RecvComplete(const nsresult& aResult)
    2714             : {
    2715           0 :   AssertIsOnOwningThread();
    2716             : 
    2717           0 :   MaybeCollectGarbageOnIPCMessage();
    2718             : 
    2719           0 :   if (!mTransaction) {
    2720           0 :     return IPC_OK();
    2721             :   }
    2722             : 
    2723           0 :   MOZ_ASSERT(mOpenDBRequest);
    2724             : 
    2725           0 :   IDBDatabase* database = mTransaction->Database();
    2726           0 :   MOZ_ASSERT(database);
    2727             : 
    2728           0 :   database->ExitSetVersionTransaction();
    2729             : 
    2730           0 :   if (NS_FAILED(aResult)) {
    2731           0 :     database->Close();
    2732             :   }
    2733             : 
    2734           0 :   mTransaction->FireCompleteOrAbortEvents(aResult);
    2735             : 
    2736           0 :   mOpenDBRequest->SetTransaction(nullptr);
    2737           0 :   mOpenDBRequest = nullptr;
    2738             : 
    2739           0 :   NoteComplete();
    2740           0 :   return IPC_OK();
    2741             : }
    2742             : 
    2743             : PBackgroundIDBRequestChild*
    2744           0 : BackgroundVersionChangeTransactionChild::AllocPBackgroundIDBRequestChild(
    2745             :                                                    const RequestParams& aParams)
    2746             : {
    2747           0 :   MOZ_CRASH("PBackgroundIDBRequestChild actors should be manually "
    2748             :             "constructed!");
    2749             : }
    2750             : 
    2751             : bool
    2752           0 : BackgroundVersionChangeTransactionChild::DeallocPBackgroundIDBRequestChild(
    2753             :                                              PBackgroundIDBRequestChild* aActor)
    2754             : {
    2755           0 :   MOZ_ASSERT(aActor);
    2756             : 
    2757           0 :   delete static_cast<BackgroundRequestChild*>(aActor);
    2758           0 :   return true;
    2759             : }
    2760             : 
    2761             : PBackgroundIDBCursorChild*
    2762           0 : BackgroundVersionChangeTransactionChild::AllocPBackgroundIDBCursorChild(
    2763             :                                                 const OpenCursorParams& aParams)
    2764             : {
    2765           0 :   AssertIsOnOwningThread();
    2766             : 
    2767           0 :   MOZ_CRASH("PBackgroundIDBCursorChild actors should be manually constructed!");
    2768             : }
    2769             : 
    2770             : bool
    2771           0 : BackgroundVersionChangeTransactionChild::DeallocPBackgroundIDBCursorChild(
    2772             :                                               PBackgroundIDBCursorChild* aActor)
    2773             : {
    2774           0 :   MOZ_ASSERT(aActor);
    2775             : 
    2776           0 :   delete static_cast<BackgroundCursorChild*>(aActor);
    2777           0 :   return true;
    2778             : }
    2779             : 
    2780             : /*******************************************************************************
    2781             :  * BackgroundMutableFileChild
    2782             :  ******************************************************************************/
    2783             : 
    2784           0 : BackgroundMutableFileChild::BackgroundMutableFileChild(const nsAString& aName,
    2785           0 :                                                        const nsAString& aType)
    2786             :   : mMutableFile(nullptr)
    2787             :   , mName(aName)
    2788           0 :   , mType(aType)
    2789             : {
    2790             :   // Can't assert owning thread here because IPDL has not yet set our manager!
    2791           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundMutableFileChild);
    2792           0 : }
    2793             : 
    2794           0 : BackgroundMutableFileChild::~BackgroundMutableFileChild()
    2795             : {
    2796           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundMutableFileChild);
    2797           0 : }
    2798             : 
    2799             : #ifdef DEBUG
    2800             : 
    2801             : void
    2802           0 : BackgroundMutableFileChild::AssertIsOnOwningThread() const
    2803             : {
    2804           0 :   static_cast<BackgroundDatabaseChild*>(Manager())->AssertIsOnOwningThread();
    2805           0 : }
    2806             : 
    2807             : #endif // DEBUG
    2808             : 
    2809             : void
    2810           0 : BackgroundMutableFileChild::EnsureDOMObject()
    2811             : {
    2812           0 :   AssertIsOnOwningThread();
    2813             : 
    2814           0 :   if (mTemporaryStrongMutableFile) {
    2815           0 :     return;
    2816             :   }
    2817             : 
    2818             :   auto database =
    2819           0 :     static_cast<BackgroundDatabaseChild*>(Manager())->GetDOMObject();
    2820           0 :   MOZ_ASSERT(database);
    2821             : 
    2822             :   mTemporaryStrongMutableFile =
    2823           0 :     new IDBMutableFile(database, this, mName, mType);
    2824             : 
    2825           0 :   MOZ_ASSERT(mTemporaryStrongMutableFile);
    2826           0 :   mTemporaryStrongMutableFile->AssertIsOnOwningThread();
    2827             : 
    2828           0 :   mMutableFile = mTemporaryStrongMutableFile;
    2829             : }
    2830             : 
    2831             : void
    2832           0 : BackgroundMutableFileChild::ReleaseDOMObject()
    2833             : {
    2834           0 :   AssertIsOnOwningThread();
    2835           0 :   MOZ_ASSERT(mTemporaryStrongMutableFile);
    2836           0 :   mTemporaryStrongMutableFile->AssertIsOnOwningThread();
    2837           0 :   MOZ_ASSERT(mMutableFile == mTemporaryStrongMutableFile);
    2838             : 
    2839           0 :   mTemporaryStrongMutableFile = nullptr;
    2840           0 : }
    2841             : 
    2842             : void
    2843           0 : BackgroundMutableFileChild::SendDeleteMeInternal()
    2844             : {
    2845           0 :   AssertIsOnOwningThread();
    2846           0 :   MOZ_ASSERT(!mTemporaryStrongMutableFile);
    2847             : 
    2848           0 :   if (mMutableFile) {
    2849           0 :     mMutableFile->ClearBackgroundActor();
    2850           0 :     mMutableFile = nullptr;
    2851             : 
    2852           0 :     MOZ_ALWAYS_TRUE(PBackgroundMutableFileChild::SendDeleteMe());
    2853             :   }
    2854           0 : }
    2855             : 
    2856             : void
    2857           0 : BackgroundMutableFileChild::ActorDestroy(ActorDestroyReason aWhy)
    2858             : {
    2859           0 :   AssertIsOnOwningThread();
    2860             : 
    2861           0 :   if (mMutableFile) {
    2862           0 :     mMutableFile->ClearBackgroundActor();
    2863             : #ifdef DEBUG
    2864           0 :     mMutableFile = nullptr;
    2865             : #endif
    2866             :   }
    2867           0 : }
    2868             : 
    2869             : PBackgroundFileHandleChild*
    2870           0 : BackgroundMutableFileChild::AllocPBackgroundFileHandleChild(
    2871             :                                                           const FileMode& aMode)
    2872             : {
    2873           0 :   MOZ_CRASH("PBackgroundFileHandleChild actors should be manually "
    2874             :             "constructed!");
    2875             : }
    2876             : 
    2877             : bool
    2878           0 : BackgroundMutableFileChild::DeallocPBackgroundFileHandleChild(
    2879             :                                              PBackgroundFileHandleChild* aActor)
    2880             : {
    2881           0 :   AssertIsOnOwningThread();
    2882           0 :   MOZ_ASSERT(aActor);
    2883             : 
    2884           0 :   delete static_cast<BackgroundFileHandleChild*>(aActor);
    2885           0 :   return true;
    2886             : }
    2887             : 
    2888             : /*******************************************************************************
    2889             :  * BackgroundRequestChild
    2890             :  ******************************************************************************/
    2891             : 
    2892           0 : BackgroundRequestChild::BackgroundRequestChild(IDBRequest* aRequest)
    2893             :   : BackgroundRequestChildBase(aRequest)
    2894             :   , mTransaction(aRequest->GetTransaction())
    2895             :   , mRunningPreprocessHelpers(0)
    2896             :   , mCurrentModuleSetIndex(0)
    2897             :   , mPreprocessResultCode(NS_OK)
    2898           0 :   , mGetAll(false)
    2899             : {
    2900           0 :   MOZ_ASSERT(mTransaction);
    2901           0 :   mTransaction->AssertIsOnOwningThread();
    2902             : 
    2903           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundRequestChild);
    2904           0 : }
    2905             : 
    2906           0 : BackgroundRequestChild::~BackgroundRequestChild()
    2907             : {
    2908           0 :   AssertIsOnOwningThread();
    2909           0 :   MOZ_ASSERT(!mTransaction);
    2910             : 
    2911           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundRequestChild);
    2912           0 : }
    2913             : 
    2914             : void
    2915           0 : BackgroundRequestChild::MaybeSendContinue()
    2916             : {
    2917           0 :   AssertIsOnOwningThread();
    2918           0 :   MOZ_ASSERT(mRunningPreprocessHelpers > 0);
    2919             : 
    2920           0 :   if (--mRunningPreprocessHelpers == 0) {
    2921           0 :     PreprocessResponse response;
    2922             : 
    2923           0 :     if (NS_SUCCEEDED(mPreprocessResultCode)) {
    2924           0 :       if (mGetAll) {
    2925           0 :         response = ObjectStoreGetAllPreprocessResponse();
    2926             :       } else {
    2927           0 :         response = ObjectStoreGetPreprocessResponse();
    2928             :       }
    2929             :     } else {
    2930           0 :       response = mPreprocessResultCode;
    2931             :     }
    2932             : 
    2933           0 :     MOZ_ALWAYS_TRUE(SendContinue(response));
    2934             :   }
    2935           0 : }
    2936             : 
    2937             : void
    2938           0 : BackgroundRequestChild::OnPreprocessFinished(
    2939             :                                    uint32_t aModuleSetIndex,
    2940             :                                    nsTArray<RefPtr<JS::WasmModule>>& aModuleSet)
    2941             : {
    2942           0 :   AssertIsOnOwningThread();
    2943           0 :   MOZ_ASSERT(aModuleSetIndex < mPreprocessHelpers.Length());
    2944           0 :   MOZ_ASSERT(!aModuleSet.IsEmpty());
    2945           0 :   MOZ_ASSERT(mPreprocessHelpers[aModuleSetIndex]);
    2946           0 :   MOZ_ASSERT(mModuleSets[aModuleSetIndex].IsEmpty());
    2947             : 
    2948           0 :   mModuleSets[aModuleSetIndex].SwapElements(aModuleSet);
    2949             : 
    2950           0 :   MaybeSendContinue();
    2951             : 
    2952           0 :   mPreprocessHelpers[aModuleSetIndex] = nullptr;
    2953           0 : }
    2954             : 
    2955             : void
    2956           0 : BackgroundRequestChild::OnPreprocessFailed(uint32_t aModuleSetIndex,
    2957             :                                            nsresult aErrorCode)
    2958             : {
    2959           0 :   AssertIsOnOwningThread();
    2960           0 :   MOZ_ASSERT(aModuleSetIndex < mPreprocessHelpers.Length());
    2961           0 :   MOZ_ASSERT(NS_FAILED(aErrorCode));
    2962           0 :   MOZ_ASSERT(mPreprocessHelpers[aModuleSetIndex]);
    2963           0 :   MOZ_ASSERT(mModuleSets[aModuleSetIndex].IsEmpty());
    2964             : 
    2965           0 :   if (NS_SUCCEEDED(mPreprocessResultCode)) {
    2966           0 :     mPreprocessResultCode = aErrorCode;
    2967             :   }
    2968             : 
    2969           0 :   MaybeSendContinue();
    2970             : 
    2971           0 :   mPreprocessHelpers[aModuleSetIndex] = nullptr;
    2972           0 : }
    2973             : 
    2974             : const nsTArray<RefPtr<JS::WasmModule>>*
    2975           0 : BackgroundRequestChild::GetNextModuleSet(const StructuredCloneReadInfo& aInfo)
    2976             : {
    2977           0 :   if (!aInfo.mHasPreprocessInfo) {
    2978           0 :     return nullptr;
    2979             :   }
    2980             : 
    2981           0 :   MOZ_ASSERT(mCurrentModuleSetIndex < mModuleSets.Length());
    2982           0 :   MOZ_ASSERT(!mModuleSets[mCurrentModuleSetIndex].IsEmpty());
    2983           0 :   return &mModuleSets[mCurrentModuleSetIndex++];
    2984             : }
    2985             : 
    2986             : void
    2987           0 : BackgroundRequestChild::HandleResponse(nsresult aResponse)
    2988             : {
    2989           0 :   AssertIsOnOwningThread();
    2990           0 :   MOZ_ASSERT(NS_FAILED(aResponse));
    2991           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aResponse) == NS_ERROR_MODULE_DOM_INDEXEDDB);
    2992           0 :   MOZ_ASSERT(mTransaction);
    2993             : 
    2994           0 :   DispatchErrorEvent(mRequest, aResponse, mTransaction);
    2995           0 : }
    2996             : 
    2997             : void
    2998           0 : BackgroundRequestChild::HandleResponse(const Key& aResponse)
    2999             : {
    3000           0 :   AssertIsOnOwningThread();
    3001             : 
    3002           0 :   ResultHelper helper(mRequest, mTransaction, &aResponse);
    3003             : 
    3004           0 :   DispatchSuccessEvent(&helper);
    3005           0 : }
    3006             : 
    3007             : void
    3008           0 : BackgroundRequestChild::HandleResponse(const nsTArray<Key>& aResponse)
    3009             : {
    3010           0 :   AssertIsOnOwningThread();
    3011             : 
    3012           0 :   ResultHelper helper(mRequest, mTransaction, &aResponse);
    3013             : 
    3014           0 :   DispatchSuccessEvent(&helper);
    3015           0 : }
    3016             : 
    3017             : void
    3018           0 : BackgroundRequestChild::HandleResponse(
    3019             :                              const SerializedStructuredCloneReadInfo& aResponse)
    3020             : {
    3021           0 :   AssertIsOnOwningThread();
    3022             : 
    3023             :   // XXX Fix this somehow...
    3024             :   auto& serializedCloneInfo =
    3025           0 :     const_cast<SerializedStructuredCloneReadInfo&>(aResponse);
    3026             : 
    3027           0 :   StructuredCloneReadInfo cloneReadInfo(Move(serializedCloneInfo));
    3028             : 
    3029           0 :   DeserializeStructuredCloneFiles(mTransaction->Database(),
    3030             :                                   aResponse.files(),
    3031             :                                   GetNextModuleSet(cloneReadInfo),
    3032           0 :                                   cloneReadInfo.mFiles);
    3033             : 
    3034           0 :   ResultHelper helper(mRequest, mTransaction, &cloneReadInfo);
    3035             : 
    3036           0 :   DispatchSuccessEvent(&helper);
    3037           0 : }
    3038             : 
    3039             : void
    3040           0 : BackgroundRequestChild::HandleResponse(
    3041             :                    const nsTArray<SerializedStructuredCloneReadInfo>& aResponse)
    3042             : {
    3043           0 :   AssertIsOnOwningThread();
    3044             : 
    3045           0 :   nsTArray<StructuredCloneReadInfo> cloneReadInfos;
    3046             : 
    3047           0 :   if (!aResponse.IsEmpty()) {
    3048           0 :     const uint32_t count = aResponse.Length();
    3049             : 
    3050           0 :     cloneReadInfos.SetCapacity(count);
    3051             : 
    3052           0 :     IDBDatabase* database = mTransaction->Database();
    3053             : 
    3054           0 :     for (uint32_t index = 0; index < count; index++) {
    3055             :       // XXX Fix this somehow...
    3056             :       auto& serializedCloneInfo =
    3057           0 :         const_cast<SerializedStructuredCloneReadInfo&>(aResponse[index]);
    3058             : 
    3059           0 :       StructuredCloneReadInfo* cloneReadInfo = cloneReadInfos.AppendElement();
    3060             : 
    3061             :       // Move relevant data into the cloneReadInfo
    3062           0 :       *cloneReadInfo = Move(serializedCloneInfo);
    3063             : 
    3064             :       // Get the files
    3065           0 :       nsTArray<StructuredCloneFile> files;
    3066           0 :       DeserializeStructuredCloneFiles(database,
    3067           0 :                                       serializedCloneInfo.files(),
    3068             :                                       GetNextModuleSet(*cloneReadInfo),
    3069           0 :                                       files);
    3070             : 
    3071           0 :       cloneReadInfo->mFiles = Move(files);
    3072             :     }
    3073             :   }
    3074             : 
    3075           0 :   ResultHelper helper(mRequest, mTransaction, &cloneReadInfos);
    3076             : 
    3077           0 :   DispatchSuccessEvent(&helper);
    3078           0 : }
    3079             : 
    3080             : void
    3081           0 : BackgroundRequestChild::HandleResponse(JS::Handle<JS::Value> aResponse)
    3082             : {
    3083           0 :   AssertIsOnOwningThread();
    3084             : 
    3085           0 :   ResultHelper helper(mRequest, mTransaction, &aResponse);
    3086             : 
    3087           0 :   DispatchSuccessEvent(&helper);
    3088           0 : }
    3089             : 
    3090             : void
    3091           0 : BackgroundRequestChild::HandleResponse(uint64_t aResponse)
    3092             : {
    3093           0 :   AssertIsOnOwningThread();
    3094             : 
    3095           0 :   JS::Value response(JS::NumberValue(aResponse));
    3096             : 
    3097           0 :   ResultHelper helper(mRequest, mTransaction, &response);
    3098             : 
    3099           0 :   DispatchSuccessEvent(&helper);
    3100           0 : }
    3101             : 
    3102             : nsresult
    3103           0 : BackgroundRequestChild::HandlePreprocess(
    3104             :                                 const WasmModulePreprocessInfo& aPreprocessInfo)
    3105             : {
    3106           0 :   AssertIsOnOwningThread();
    3107             : 
    3108           0 :   IDBDatabase* database = mTransaction->Database();
    3109             : 
    3110           0 :   mPreprocessHelpers.SetLength(1);
    3111             : 
    3112           0 :   nsTArray<StructuredCloneFile> files;
    3113           0 :   DeserializeStructuredCloneFiles(database,
    3114             :                                   aPreprocessInfo.files(),
    3115             :                                   nullptr,
    3116           0 :                                   files);
    3117             : 
    3118             : 
    3119           0 :   RefPtr<PreprocessHelper>& preprocessHelper = mPreprocessHelpers[0];
    3120           0 :   preprocessHelper = new PreprocessHelper(0, this);
    3121             : 
    3122           0 :   nsresult rv = preprocessHelper->Init(files);
    3123           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    3124           0 :     return rv;
    3125             :   }
    3126             : 
    3127           0 :   rv = preprocessHelper->Dispatch();
    3128           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    3129           0 :     return rv;
    3130             :   }
    3131             : 
    3132           0 :   mRunningPreprocessHelpers++;
    3133             : 
    3134           0 :   mModuleSets.SetLength(1);
    3135             : 
    3136           0 :   return NS_OK;
    3137             : }
    3138             : 
    3139             : nsresult
    3140           0 : BackgroundRequestChild::HandlePreprocess(
    3141             :                      const nsTArray<WasmModulePreprocessInfo>& aPreprocessInfos)
    3142             : {
    3143           0 :   AssertIsOnOwningThread();
    3144             : 
    3145           0 :   IDBDatabase* database = mTransaction->Database();
    3146             : 
    3147           0 :   uint32_t count = aPreprocessInfos.Length();
    3148             : 
    3149           0 :   mPreprocessHelpers.SetLength(count);
    3150             : 
    3151             :   // TODO: Since we use the stream transport service, this can spawn 25 threads
    3152             :   //       and has the potential to cause some annoying browser hiccups.
    3153             :   //       Consider using a single thread or a very small threadpool.
    3154           0 :   for (uint32_t index = 0; index < count; index++) {
    3155           0 :     const WasmModulePreprocessInfo& preprocessInfo = aPreprocessInfos[index];
    3156             : 
    3157           0 :     nsTArray<StructuredCloneFile> files;
    3158           0 :     DeserializeStructuredCloneFiles(database,
    3159             :                                     preprocessInfo.files(),
    3160             :                                     nullptr,
    3161           0 :                                     files);
    3162             : 
    3163             : 
    3164           0 :     RefPtr<PreprocessHelper>& preprocessHelper = mPreprocessHelpers[index];
    3165           0 :     preprocessHelper = new PreprocessHelper(index, this);
    3166             : 
    3167           0 :     nsresult rv = preprocessHelper->Init(files);
    3168           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
    3169           0 :       return rv;
    3170             :     }
    3171             : 
    3172           0 :     rv = preprocessHelper->Dispatch();
    3173           0 :     if (NS_WARN_IF(NS_FAILED(rv))) {
    3174           0 :       return rv;
    3175             :     }
    3176             : 
    3177           0 :     mRunningPreprocessHelpers++;
    3178             :   }
    3179             : 
    3180           0 :   mModuleSets.SetLength(count);
    3181             : 
    3182           0 :   mGetAll = true;
    3183             : 
    3184           0 :   return NS_OK;
    3185             : }
    3186             : 
    3187             : void
    3188           0 : BackgroundRequestChild::ActorDestroy(ActorDestroyReason aWhy)
    3189             : {
    3190           0 :   AssertIsOnOwningThread();
    3191             : 
    3192           0 :   MaybeCollectGarbageOnIPCMessage();
    3193             : 
    3194           0 :   for (uint32_t count = mPreprocessHelpers.Length(), index = 0;
    3195           0 :        index < count;
    3196             :        index++) {
    3197           0 :     RefPtr<PreprocessHelper>& preprocessHelper = mPreprocessHelpers[index];
    3198             : 
    3199           0 :     if (preprocessHelper) {
    3200           0 :       preprocessHelper->ClearActor();
    3201             : 
    3202           0 :       preprocessHelper = nullptr;
    3203             :     }
    3204             :   }
    3205             : 
    3206           0 :   if (mTransaction) {
    3207           0 :     mTransaction->AssertIsOnOwningThread();
    3208             : 
    3209           0 :     mTransaction->OnRequestFinished(/* aActorDestroyedNormally */
    3210           0 :                                     aWhy == Deletion);
    3211             : #ifdef DEBUG
    3212           0 :     mTransaction = nullptr;
    3213             : #endif
    3214             :   }
    3215           0 : }
    3216             : 
    3217             : mozilla::ipc::IPCResult
    3218           0 : BackgroundRequestChild::Recv__delete__(const RequestResponse& aResponse)
    3219             : {
    3220           0 :   AssertIsOnOwningThread();
    3221           0 :   MOZ_ASSERT(mRequest);
    3222           0 :   MOZ_ASSERT(mTransaction);
    3223             : 
    3224           0 :   MaybeCollectGarbageOnIPCMessage();
    3225             : 
    3226           0 :   if (mTransaction->IsAborted()) {
    3227             :     // Always fire an "error" event with ABORT_ERR if the transaction was
    3228             :     // aborted, even if the request succeeded or failed with another error.
    3229           0 :     HandleResponse(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
    3230             :   } else {
    3231           0 :     switch (aResponse.type()) {
    3232             :       case RequestResponse::Tnsresult:
    3233           0 :         HandleResponse(aResponse.get_nsresult());
    3234           0 :         break;
    3235             : 
    3236             :       case RequestResponse::TObjectStoreAddResponse:
    3237           0 :         HandleResponse(aResponse.get_ObjectStoreAddResponse().key());
    3238           0 :         break;
    3239             : 
    3240             :       case RequestResponse::TObjectStorePutResponse:
    3241           0 :         HandleResponse(aResponse.get_ObjectStorePutResponse().key());
    3242           0 :         break;
    3243             : 
    3244             :       case RequestResponse::TObjectStoreGetResponse:
    3245           0 :         HandleResponse(aResponse.get_ObjectStoreGetResponse().cloneInfo());
    3246           0 :         break;
    3247             : 
    3248             :       case RequestResponse::TObjectStoreGetKeyResponse:
    3249           0 :         HandleResponse(aResponse.get_ObjectStoreGetKeyResponse().key());
    3250           0 :         break;
    3251             : 
    3252             :       case RequestResponse::TObjectStoreGetAllResponse:
    3253           0 :         HandleResponse(aResponse.get_ObjectStoreGetAllResponse().cloneInfos());
    3254           0 :         break;
    3255             : 
    3256             :       case RequestResponse::TObjectStoreGetAllKeysResponse:
    3257           0 :         HandleResponse(aResponse.get_ObjectStoreGetAllKeysResponse().keys());
    3258           0 :         break;
    3259             : 
    3260             :       case RequestResponse::TObjectStoreDeleteResponse:
    3261           0 :         HandleResponse(JS::UndefinedHandleValue);
    3262           0 :         break;
    3263             : 
    3264             :       case RequestResponse::TObjectStoreClearResponse:
    3265           0 :         HandleResponse(JS::UndefinedHandleValue);
    3266           0 :         break;
    3267             : 
    3268             :       case RequestResponse::TObjectStoreCountResponse:
    3269           0 :         HandleResponse(aResponse.get_ObjectStoreCountResponse().count());
    3270           0 :         break;
    3271             : 
    3272             :       case RequestResponse::TIndexGetResponse:
    3273           0 :         HandleResponse(aResponse.get_IndexGetResponse().cloneInfo());
    3274           0 :         break;
    3275             : 
    3276             :       case RequestResponse::TIndexGetKeyResponse:
    3277           0 :         HandleResponse(aResponse.get_IndexGetKeyResponse().key());
    3278           0 :         break;
    3279             : 
    3280             :       case RequestResponse::TIndexGetAllResponse:
    3281           0 :         HandleResponse(aResponse.get_IndexGetAllResponse().cloneInfos());
    3282           0 :         break;
    3283             : 
    3284             :       case RequestResponse::TIndexGetAllKeysResponse:
    3285           0 :         HandleResponse(aResponse.get_IndexGetAllKeysResponse().keys());
    3286           0 :         break;
    3287             : 
    3288             :       case RequestResponse::TIndexCountResponse:
    3289           0 :         HandleResponse(aResponse.get_IndexCountResponse().count());
    3290           0 :         break;
    3291             : 
    3292             :       default:
    3293           0 :         MOZ_CRASH("Unknown response type!");
    3294             :     }
    3295             :   }
    3296             : 
    3297           0 :   mTransaction->OnRequestFinished(/* aActorDestroyedNormally */ true);
    3298             : 
    3299             :   // Null this out so that we don't try to call OnRequestFinished() again in
    3300             :   // ActorDestroy.
    3301           0 :   mTransaction = nullptr;
    3302             : 
    3303           0 :   return IPC_OK();
    3304             : }
    3305             : 
    3306             : mozilla::ipc::IPCResult
    3307           0 : BackgroundRequestChild::RecvPreprocess(const PreprocessParams& aParams)
    3308             : {
    3309           0 :   AssertIsOnOwningThread();
    3310           0 :   MOZ_ASSERT(mTransaction);
    3311             : 
    3312           0 :   MaybeCollectGarbageOnIPCMessage();
    3313             : 
    3314             :   nsresult rv;
    3315             : 
    3316           0 :   switch (aParams.type()) {
    3317             :     case PreprocessParams::TObjectStoreGetPreprocessParams: {
    3318             :       ObjectStoreGetPreprocessParams params =
    3319           0 :         aParams.get_ObjectStoreGetPreprocessParams();
    3320             : 
    3321           0 :       rv = HandlePreprocess(params.preprocessInfo());
    3322             : 
    3323           0 :       break;
    3324             :     }
    3325             : 
    3326             :     case PreprocessParams::TObjectStoreGetAllPreprocessParams: {
    3327             :       ObjectStoreGetAllPreprocessParams params =
    3328           0 :         aParams.get_ObjectStoreGetAllPreprocessParams();
    3329             : 
    3330           0 :       rv = HandlePreprocess(params.preprocessInfos());
    3331             : 
    3332           0 :       break;
    3333             :     }
    3334             : 
    3335             :     default:
    3336           0 :       MOZ_CRASH("Unknown params type!");
    3337             :   }
    3338             : 
    3339           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    3340           0 :     if (!SendContinue(rv)) {
    3341           0 :       return IPC_FAIL_NO_REASON(this);
    3342             :     }
    3343           0 :     return IPC_OK();
    3344             :   }
    3345             : 
    3346           0 :   return IPC_OK();
    3347             : }
    3348             : 
    3349             : nsresult
    3350           0 : BackgroundRequestChild::
    3351             : PreprocessHelper::Init(const nsTArray<StructuredCloneFile>& aFiles)
    3352             : {
    3353           0 :   AssertIsOnOwningThread();
    3354           0 :   MOZ_ASSERT(!aFiles.IsEmpty());
    3355             : 
    3356           0 :   uint32_t count = aFiles.Length();
    3357             : 
    3358             :   // We should receive even number of files.
    3359           0 :   MOZ_ASSERT(count % 2 == 0);
    3360             : 
    3361             :   // Let's process it as pairs.
    3362           0 :   count = count / 2;
    3363             : 
    3364           0 :   nsTArray<StreamPair> streamPairs;
    3365           0 :   for (uint32_t index = 0; index < count; index++) {
    3366           0 :     uint32_t bytecodeIndex = index * 2;
    3367           0 :     uint32_t compiledIndex = bytecodeIndex + 1;
    3368             : 
    3369           0 :     const StructuredCloneFile& bytecodeFile = aFiles[bytecodeIndex];
    3370           0 :     const StructuredCloneFile& compiledFile = aFiles[compiledIndex];
    3371             : 
    3372           0 :     MOZ_ASSERT(bytecodeFile.mType == StructuredCloneFile::eWasmBytecode);
    3373           0 :     MOZ_ASSERT(bytecodeFile.mBlob);
    3374           0 :     MOZ_ASSERT(compiledFile.mType == StructuredCloneFile::eWasmCompiled);
    3375           0 :     MOZ_ASSERT(compiledFile.mBlob);
    3376             : 
    3377           0 :     ErrorResult errorResult;
    3378             : 
    3379           0 :     nsCOMPtr<nsIInputStream> bytecodeStream;
    3380           0 :     bytecodeFile.mBlob->GetInternalStream(getter_AddRefs(bytecodeStream),
    3381           0 :                                           errorResult);
    3382           0 :     if (NS_WARN_IF(errorResult.Failed())) {
    3383           0 :       return errorResult.StealNSResult();
    3384             :     }
    3385             : 
    3386           0 :     nsCOMPtr<nsIInputStream> compiledStream;
    3387           0 :     compiledFile.mBlob->GetInternalStream(getter_AddRefs(compiledStream),
    3388           0 :                                           errorResult);
    3389           0 :     if (NS_WARN_IF(errorResult.Failed())) {
    3390           0 :       return errorResult.StealNSResult();
    3391             :     }
    3392             : 
    3393           0 :     streamPairs.AppendElement(StreamPair(bytecodeStream, compiledStream));
    3394             :   }
    3395             : 
    3396           0 :   mStreamPairs = Move(streamPairs);
    3397             : 
    3398           0 :   return NS_OK;
    3399             : }
    3400             : 
    3401             : nsresult
    3402           0 : BackgroundRequestChild::
    3403             : PreprocessHelper::Dispatch()
    3404             : {
    3405           0 :   AssertIsOnOwningThread();
    3406             : 
    3407           0 :   if (!mTaskQueue) {
    3408             :     // The stream transport service is used for asynchronous processing. It has
    3409             :     // a threadpool with a high cap of 25 threads. Fortunately, the service can
    3410             :     // be used on workers too.
    3411             :     nsCOMPtr<nsIEventTarget> target =
    3412           0 :       do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
    3413           0 :     MOZ_ASSERT(target);
    3414             : 
    3415             :     // We use a TaskQueue here in order to be sure that the events are
    3416             :     // dispatched in the correct order. This is not guaranteed in case we use
    3417             :     // the I/O thread directly.
    3418           0 :     mTaskQueue = new TaskQueue(target.forget());
    3419           0 :     mTaskQueueEventTarget = mTaskQueue->WrapAsEventTarget();
    3420             :   }
    3421             : 
    3422           0 :   nsresult rv = mTaskQueueEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
    3423           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    3424           0 :     return rv;
    3425             :   }
    3426             : 
    3427           0 :   return NS_OK;
    3428             : }
    3429             : 
    3430             : void
    3431           0 : BackgroundRequestChild::
    3432             : PreprocessHelper::RunOnOwningThread()
    3433             : {
    3434           0 :   AssertIsOnOwningThread();
    3435             : 
    3436           0 :   if (mActor) {
    3437           0 :     if (NS_SUCCEEDED(mResultCode)) {
    3438           0 :       mActor->OnPreprocessFinished(mModuleSetIndex, mModuleSet);
    3439             : 
    3440           0 :       MOZ_ASSERT(mModuleSet.IsEmpty());
    3441             :     } else {
    3442           0 :       mActor->OnPreprocessFailed(mModuleSetIndex, mResultCode);
    3443             :     }
    3444             :   }
    3445           0 : }
    3446             : 
    3447             : void
    3448           0 : BackgroundRequestChild::
    3449             : PreprocessHelper::ProcessCurrentStreamPair()
    3450             : {
    3451           0 :   MOZ_ASSERT(!IsOnOwningThread());
    3452           0 :   MOZ_ASSERT(!mStreamPairs.IsEmpty());
    3453             : 
    3454             :   nsresult rv;
    3455             : 
    3456           0 :   const StreamPair& streamPair = mStreamPairs[0];
    3457             : 
    3458             :   // We still don't have the current bytecode FileDesc.
    3459           0 :   if (!mCurrentBytecodeFileDesc) {
    3460           0 :     const nsCOMPtr<nsIInputStream>& bytecodeStream = streamPair.first;
    3461           0 :     MOZ_ASSERT(bytecodeStream);
    3462             : 
    3463           0 :     mCurrentBytecodeFileDesc = GetFileDescriptorFromStream(bytecodeStream);
    3464           0 :     if (!mCurrentBytecodeFileDesc) {
    3465           0 :       rv = WaitForStreamReady(bytecodeStream);
    3466           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
    3467           0 :         ContinueWithStatus(rv);
    3468             :       }
    3469           0 :       return;
    3470             :     }
    3471             :   }
    3472             : 
    3473           0 :   if (!mCurrentCompiledFileDesc) {
    3474           0 :     const nsCOMPtr<nsIInputStream>& compiledStream = streamPair.second;
    3475           0 :     MOZ_ASSERT(compiledStream);
    3476             : 
    3477           0 :     mCurrentCompiledFileDesc = GetFileDescriptorFromStream(compiledStream);
    3478           0 :     if (!mCurrentCompiledFileDesc) {
    3479           0 :       rv = WaitForStreamReady(compiledStream);
    3480           0 :       if (NS_WARN_IF(NS_FAILED(rv))) {
    3481           0 :         ContinueWithStatus(rv);
    3482             :       }
    3483           0 :       return;
    3484             :     }
    3485             :   }
    3486             : 
    3487           0 :   MOZ_ASSERT(mCurrentBytecodeFileDesc && mCurrentCompiledFileDesc);
    3488             : 
    3489           0 :   JS::BuildIdCharVector buildId;
    3490           0 :   bool ok = GetBuildId(&buildId);
    3491           0 :   if (NS_WARN_IF(!ok)) {
    3492           0 :     ContinueWithStatus(NS_ERROR_FAILURE);
    3493           0 :     return;
    3494             :   }
    3495             : 
    3496             :   RefPtr<JS::WasmModule> module =
    3497             :     JS::DeserializeWasmModule(mCurrentBytecodeFileDesc,
    3498             :                               mCurrentCompiledFileDesc,
    3499           0 :                               Move(buildId),
    3500             :                               nullptr,
    3501             :                               0,
    3502           0 :                               0);
    3503           0 :   if (NS_WARN_IF(!module)) {
    3504           0 :     ContinueWithStatus(NS_ERROR_FAILURE);
    3505           0 :     return;
    3506             :   }
    3507             : 
    3508           0 :   mModuleSet.AppendElement(module);
    3509           0 :   mStreamPairs.RemoveElementAt(0);
    3510             : 
    3511           0 :   ContinueWithStatus(NS_OK);
    3512             : }
    3513             : 
    3514             : nsresult
    3515           0 : BackgroundRequestChild::
    3516             : PreprocessHelper::WaitForStreamReady(nsIInputStream* aInputStream)
    3517             : {
    3518           0 :   MOZ_ASSERT(!IsOnOwningThread());
    3519           0 :   MOZ_ASSERT(aInputStream);
    3520             : 
    3521           0 :   nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aInputStream);
    3522           0 :   if (!asyncStream) {
    3523           0 :     return NS_ERROR_NO_INTERFACE;
    3524             :   }
    3525             : 
    3526           0 :   nsresult rv = asyncStream->AsyncWait(this, 0, 0, mTaskQueueEventTarget);
    3527           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    3528           0 :     return rv;
    3529             :   }
    3530             : 
    3531           0 :   return NS_OK;
    3532             : }
    3533             : 
    3534             : void
    3535           0 : BackgroundRequestChild::
    3536             : PreprocessHelper::ContinueWithStatus(nsresult aStatus)
    3537             : {
    3538           0 :   MOZ_ASSERT(!IsOnOwningThread());
    3539             : 
    3540             :   // Let's reset the value for the next operation.
    3541           0 :   mCurrentBytecodeFileDesc = nullptr;
    3542           0 :   mCurrentCompiledFileDesc = nullptr;
    3543             : 
    3544           0 :   nsCOMPtr<nsIEventTarget> eventTarget;
    3545             : 
    3546           0 :   if (NS_WARN_IF(NS_FAILED(aStatus))) {
    3547             :     // If the previous operation failed, we don't continue the processing of the
    3548             :     // other stream pairs.
    3549           0 :     MOZ_ASSERT(mResultCode == NS_OK);
    3550           0 :     mResultCode = aStatus;
    3551             : 
    3552           0 :     eventTarget = mOwningEventTarget;
    3553           0 :   } else if (mStreamPairs.IsEmpty()) {
    3554             :     // If all the streams have been processed, we can go back to the owning
    3555             :     // thread.
    3556           0 :     eventTarget = mOwningEventTarget;
    3557             :   } else {
    3558             :     // Continue the processing.
    3559           0 :     eventTarget = mTaskQueueEventTarget;
    3560             :   }
    3561             : 
    3562           0 :   nsresult rv = eventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
    3563           0 :   Unused <<  NS_WARN_IF(NS_FAILED(rv));
    3564           0 : }
    3565             : 
    3566           0 : NS_IMPL_ISUPPORTS_INHERITED(BackgroundRequestChild::PreprocessHelper,
    3567             :                             CancelableRunnable, nsIInputStreamCallback)
    3568             : 
    3569             : NS_IMETHODIMP
    3570           0 : BackgroundRequestChild::
    3571             : PreprocessHelper::Run()
    3572             : {
    3573           0 :   if (IsOnOwningThread()) {
    3574           0 :     RunOnOwningThread();
    3575             :   } else {
    3576           0 :     ProcessCurrentStreamPair();
    3577             :   }
    3578             : 
    3579           0 :   return NS_OK;
    3580             : }
    3581             : 
    3582             : NS_IMETHODIMP
    3583           0 : BackgroundRequestChild::
    3584             : PreprocessHelper::OnInputStreamReady(nsIAsyncInputStream* aStream)
    3585             : {
    3586           0 :   MOZ_ASSERT(!IsOnOwningThread());
    3587           0 :   MOZ_ASSERT(aStream);
    3588           0 :   MOZ_ASSERT(!mStreamPairs.IsEmpty());
    3589             : 
    3590             :   // We still don't have the current bytecode FileDesc.
    3591           0 :   if (!mCurrentBytecodeFileDesc) {
    3592           0 :     mCurrentBytecodeFileDesc = GetFileDescriptorFromStream(aStream);
    3593           0 :     if (!mCurrentBytecodeFileDesc) {
    3594           0 :       ContinueWithStatus(NS_ERROR_FAILURE);
    3595           0 :       return NS_OK;
    3596             :     }
    3597             : 
    3598             :     // Let's continue with the processing of the current pair.
    3599           0 :     ProcessCurrentStreamPair();
    3600           0 :     return NS_OK;
    3601             :   }
    3602             : 
    3603           0 :   if (!mCurrentCompiledFileDesc) {
    3604           0 :     mCurrentCompiledFileDesc = GetFileDescriptorFromStream(aStream);
    3605           0 :     if (!mCurrentCompiledFileDesc) {
    3606           0 :       ContinueWithStatus(NS_ERROR_FAILURE);
    3607           0 :       return NS_OK;
    3608             :     }
    3609             : 
    3610             :     // Let's continue with the processing of the current pair.
    3611           0 :     ProcessCurrentStreamPair();
    3612           0 :     return NS_OK;
    3613             :   }
    3614             : 
    3615           0 :   MOZ_CRASH("If we have both fileDescs why are we here?");
    3616             : }
    3617             : 
    3618             : nsresult
    3619           0 : BackgroundRequestChild::
    3620             : PreprocessHelper::Cancel()
    3621             : {
    3622           0 :   return NS_OK;
    3623             : }
    3624             : 
    3625             : /*******************************************************************************
    3626             :  * BackgroundCursorChild
    3627             :  ******************************************************************************/
    3628             : 
    3629             : // Does not need to be threadsafe since this only runs on one thread, but
    3630             : // inheriting from CancelableRunnable is easy.
    3631             : class BackgroundCursorChild::DelayedActionRunnable final
    3632             :   : public CancelableRunnable
    3633             : {
    3634             :   using ActionFunc = void (BackgroundCursorChild::*)();
    3635             : 
    3636             :   BackgroundCursorChild* mActor;
    3637             :   RefPtr<IDBRequest> mRequest;
    3638             :   ActionFunc mActionFunc;
    3639             : 
    3640             : public:
    3641             :   explicit
    3642           0 :   DelayedActionRunnable(BackgroundCursorChild* aActor, ActionFunc aActionFunc)
    3643           0 :     : CancelableRunnable("indexedDB::BackgroundCursorChild::DelayedActionRunnable")
    3644             :     , mActor(aActor)
    3645             :     , mRequest(aActor->mRequest)
    3646           0 :     , mActionFunc(aActionFunc)
    3647             :   {
    3648           0 :     MOZ_ASSERT(aActor);
    3649           0 :     aActor->AssertIsOnOwningThread();
    3650           0 :     MOZ_ASSERT(mRequest);
    3651           0 :     MOZ_ASSERT(mActionFunc);
    3652           0 :   }
    3653             : 
    3654             : private:
    3655           0 :   ~DelayedActionRunnable()
    3656           0 :   { }
    3657             : 
    3658             :   NS_DECL_NSIRUNNABLE
    3659             :   nsresult Cancel() override;
    3660             : };
    3661             : 
    3662           0 : BackgroundCursorChild::BackgroundCursorChild(IDBRequest* aRequest,
    3663             :                                              IDBObjectStore* aObjectStore,
    3664           0 :                                              Direction aDirection)
    3665             :   : mRequest(aRequest)
    3666           0 :   , mTransaction(aRequest->GetTransaction())
    3667             :   , mObjectStore(aObjectStore)
    3668             :   , mIndex(nullptr)
    3669             :   , mCursor(nullptr)
    3670             :   , mStrongRequest(aRequest)
    3671           0 :   , mDirection(aDirection)
    3672             : {
    3673           0 :   MOZ_ASSERT(aObjectStore);
    3674           0 :   aObjectStore->AssertIsOnOwningThread();
    3675           0 :   MOZ_ASSERT(mTransaction);
    3676             : 
    3677           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundCursorChild);
    3678           0 : }
    3679             : 
    3680           0 : BackgroundCursorChild::BackgroundCursorChild(IDBRequest* aRequest,
    3681             :                                              IDBIndex* aIndex,
    3682           0 :                                              Direction aDirection)
    3683             :   : mRequest(aRequest)
    3684           0 :   , mTransaction(aRequest->GetTransaction())
    3685             :   , mObjectStore(nullptr)
    3686             :   , mIndex(aIndex)
    3687             :   , mCursor(nullptr)
    3688             :   , mStrongRequest(aRequest)
    3689           0 :   , mDirection(aDirection)
    3690             : {
    3691           0 :   MOZ_ASSERT(aIndex);
    3692           0 :   aIndex->AssertIsOnOwningThread();
    3693           0 :   MOZ_ASSERT(mTransaction);
    3694             : 
    3695           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundCursorChild);
    3696           0 : }
    3697             : 
    3698           0 : BackgroundCursorChild::~BackgroundCursorChild()
    3699             : {
    3700           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundCursorChild);
    3701           0 : }
    3702             : 
    3703             : void
    3704           0 : BackgroundCursorChild::SendContinueInternal(const CursorRequestParams& aParams)
    3705             : {
    3706           0 :   AssertIsOnOwningThread();
    3707           0 :   MOZ_ASSERT(mRequest);
    3708           0 :   MOZ_ASSERT(mTransaction);
    3709           0 :   MOZ_ASSERT(mCursor);
    3710           0 :   MOZ_ASSERT(!mStrongRequest);
    3711           0 :   MOZ_ASSERT(!mStrongCursor);
    3712             : 
    3713             :   // Make sure all our DOM objects stay alive.
    3714           0 :   mStrongCursor = mCursor;
    3715             : 
    3716           0 :   MOZ_ASSERT(mRequest->ReadyState() == IDBRequestReadyState::Done);
    3717           0 :   mRequest->Reset();
    3718             : 
    3719           0 :   mTransaction->OnNewRequest();
    3720             : 
    3721           0 :   MOZ_ALWAYS_TRUE(PBackgroundIDBCursorChild::SendContinue(aParams));
    3722           0 : }
    3723             : 
    3724             : void
    3725           0 : BackgroundCursorChild::SendDeleteMeInternal()
    3726             : {
    3727           0 :   AssertIsOnOwningThread();
    3728           0 :   MOZ_ASSERT(!mStrongRequest);
    3729           0 :   MOZ_ASSERT(!mStrongCursor);
    3730             : 
    3731           0 :   mRequest = nullptr;
    3732           0 :   mTransaction = nullptr;
    3733           0 :   mObjectStore = nullptr;
    3734           0 :   mIndex = nullptr;
    3735             : 
    3736           0 :   if (mCursor) {
    3737           0 :     mCursor->ClearBackgroundActor();
    3738           0 :     mCursor = nullptr;
    3739             : 
    3740           0 :     MOZ_ALWAYS_TRUE(PBackgroundIDBCursorChild::SendDeleteMe());
    3741             :   }
    3742           0 : }
    3743             : 
    3744             : void
    3745           0 : BackgroundCursorChild::HandleResponse(nsresult aResponse)
    3746             : {
    3747           0 :   AssertIsOnOwningThread();
    3748           0 :   MOZ_ASSERT(NS_FAILED(aResponse));
    3749           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aResponse) == NS_ERROR_MODULE_DOM_INDEXEDDB);
    3750           0 :   MOZ_ASSERT(mRequest);
    3751           0 :   MOZ_ASSERT(mTransaction);
    3752           0 :   MOZ_ASSERT(!mStrongRequest);
    3753           0 :   MOZ_ASSERT(!mStrongCursor);
    3754             : 
    3755           0 :   DispatchErrorEvent(mRequest, aResponse, mTransaction);
    3756           0 : }
    3757             : 
    3758             : void
    3759           0 : BackgroundCursorChild::HandleResponse(const void_t& aResponse)
    3760             : {
    3761           0 :   AssertIsOnOwningThread();
    3762           0 :   MOZ_ASSERT(mRequest);
    3763           0 :   MOZ_ASSERT(mTransaction);
    3764           0 :   MOZ_ASSERT(!mStrongRequest);
    3765           0 :   MOZ_ASSERT(!mStrongCursor);
    3766             : 
    3767           0 :   if (mCursor) {
    3768           0 :     mCursor->Reset();
    3769             :   }
    3770             : 
    3771           0 :   ResultHelper helper(mRequest, mTransaction, &JS::NullHandleValue);
    3772           0 :   DispatchSuccessEvent(&helper);
    3773             : 
    3774           0 :   if (!mCursor) {
    3775             :     nsCOMPtr<nsIRunnable> deleteRunnable = new DelayedActionRunnable(
    3776           0 :       this, &BackgroundCursorChild::SendDeleteMeInternal);
    3777           0 :       MOZ_ALWAYS_SUCCEEDS(this->GetActorEventTarget()->
    3778             :         Dispatch(deleteRunnable.forget(), NS_DISPATCH_NORMAL));
    3779             :   }
    3780           0 : }
    3781             : 
    3782             : void
    3783           0 : BackgroundCursorChild::HandleResponse(
    3784             :     const nsTArray<ObjectStoreCursorResponse>& aResponses)
    3785             : {
    3786           0 :   AssertIsOnOwningThread();
    3787           0 :   MOZ_ASSERT(mRequest);
    3788           0 :   MOZ_ASSERT(mTransaction);
    3789           0 :   MOZ_ASSERT(mObjectStore);
    3790           0 :   MOZ_ASSERT(!mStrongRequest);
    3791           0 :   MOZ_ASSERT(!mStrongCursor);
    3792             : 
    3793           0 :   MOZ_ASSERT(aResponses.Length() == 1);
    3794             : 
    3795             :   // XXX Fix this somehow...
    3796             :   auto& responses =
    3797           0 :     const_cast<nsTArray<ObjectStoreCursorResponse>&>(aResponses);
    3798             : 
    3799           0 :   for (ObjectStoreCursorResponse& response : responses) {
    3800           0 :     StructuredCloneReadInfo cloneReadInfo(Move(response.cloneInfo()));
    3801           0 :     cloneReadInfo.mDatabase = mTransaction->Database();
    3802             : 
    3803           0 :     DeserializeStructuredCloneFiles(mTransaction->Database(),
    3804           0 :                                     response.cloneInfo().files(),
    3805             :                                     nullptr,
    3806           0 :                                     cloneReadInfo.mFiles);
    3807             : 
    3808           0 :     RefPtr<IDBCursor> newCursor;
    3809             : 
    3810           0 :     if (mCursor) {
    3811           0 :       mCursor->Reset(Move(response.key()), Move(cloneReadInfo));
    3812             :     } else {
    3813           0 :       newCursor = IDBCursor::Create(this,
    3814           0 :                                     Move(response.key()),
    3815           0 :                                     Move(cloneReadInfo));
    3816           0 :       mCursor = newCursor;
    3817             :     }
    3818             :   }
    3819             : 
    3820           0 :   ResultHelper helper(mRequest, mTransaction, mCursor);
    3821           0 :   DispatchSuccessEvent(&helper);
    3822           0 : }
    3823             : 
    3824             : void
    3825           0 : BackgroundCursorChild::HandleResponse(
    3826             :                                   const ObjectStoreKeyCursorResponse& aResponse)
    3827             : {
    3828           0 :   AssertIsOnOwningThread();
    3829           0 :   MOZ_ASSERT(mRequest);
    3830           0 :   MOZ_ASSERT(mTransaction);
    3831           0 :   MOZ_ASSERT(mObjectStore);
    3832           0 :   MOZ_ASSERT(!mStrongRequest);
    3833           0 :   MOZ_ASSERT(!mStrongCursor);
    3834             : 
    3835             :   // XXX Fix this somehow...
    3836           0 :   auto& response = const_cast<ObjectStoreKeyCursorResponse&>(aResponse);
    3837             : 
    3838           0 :   RefPtr<IDBCursor> newCursor;
    3839             : 
    3840           0 :   if (mCursor) {
    3841           0 :     mCursor->Reset(Move(response.key()));
    3842             :   } else {
    3843           0 :     newCursor = IDBCursor::Create(this, Move(response.key()));
    3844           0 :     mCursor = newCursor;
    3845             :   }
    3846             : 
    3847           0 :   ResultHelper helper(mRequest, mTransaction, mCursor);
    3848           0 :   DispatchSuccessEvent(&helper);
    3849           0 : }
    3850             : 
    3851             : void
    3852           0 : BackgroundCursorChild::HandleResponse(const IndexCursorResponse& aResponse)
    3853             : {
    3854           0 :   AssertIsOnOwningThread();
    3855           0 :   MOZ_ASSERT(mRequest);
    3856           0 :   MOZ_ASSERT(mTransaction);
    3857           0 :   MOZ_ASSERT(mIndex);
    3858           0 :   MOZ_ASSERT(!mStrongRequest);
    3859           0 :   MOZ_ASSERT(!mStrongCursor);
    3860             : 
    3861             :   // XXX Fix this somehow...
    3862           0 :   auto& response = const_cast<IndexCursorResponse&>(aResponse);
    3863             : 
    3864           0 :   StructuredCloneReadInfo cloneReadInfo(Move(response.cloneInfo()));
    3865           0 :   cloneReadInfo.mDatabase = mTransaction->Database();
    3866             : 
    3867           0 :   DeserializeStructuredCloneFiles(mTransaction->Database(),
    3868           0 :                                   aResponse.cloneInfo().files(),
    3869             :                                   nullptr,
    3870           0 :                                   cloneReadInfo.mFiles);
    3871             : 
    3872           0 :   RefPtr<IDBCursor> newCursor;
    3873             : 
    3874           0 :   if (mCursor) {
    3875           0 :     mCursor->Reset(Move(response.key()),
    3876           0 :                    Move(response.sortKey()),
    3877           0 :                    Move(response.objectKey()),
    3878           0 :                    Move(cloneReadInfo));
    3879             :   } else {
    3880           0 :     newCursor = IDBCursor::Create(this,
    3881           0 :                                   Move(response.key()),
    3882           0 :                                   Move(response.sortKey()),
    3883           0 :                                   Move(response.objectKey()),
    3884           0 :                                   Move(cloneReadInfo));
    3885           0 :     mCursor = newCursor;
    3886             :   }
    3887             : 
    3888           0 :   ResultHelper helper(mRequest, mTransaction, mCursor);
    3889           0 :   DispatchSuccessEvent(&helper);
    3890           0 : }
    3891             : 
    3892             : void
    3893           0 : BackgroundCursorChild::HandleResponse(const IndexKeyCursorResponse& aResponse)
    3894             : {
    3895           0 :   AssertIsOnOwningThread();
    3896           0 :   MOZ_ASSERT(mRequest);
    3897           0 :   MOZ_ASSERT(mTransaction);
    3898           0 :   MOZ_ASSERT(mIndex);
    3899           0 :   MOZ_ASSERT(!mStrongRequest);
    3900           0 :   MOZ_ASSERT(!mStrongCursor);
    3901             : 
    3902             :   // XXX Fix this somehow...
    3903           0 :   auto& response = const_cast<IndexKeyCursorResponse&>(aResponse);
    3904             : 
    3905           0 :   RefPtr<IDBCursor> newCursor;
    3906             : 
    3907           0 :   if (mCursor) {
    3908           0 :     mCursor->Reset(Move(response.key()),
    3909           0 :                    Move(response.sortKey()),
    3910           0 :                    Move(response.objectKey()));
    3911             :   } else {
    3912           0 :     newCursor = IDBCursor::Create(this,
    3913           0 :                                   Move(response.key()),
    3914           0 :                                   Move(response.sortKey()),
    3915           0 :                                   Move(response.objectKey()));
    3916           0 :     mCursor = newCursor;
    3917             :   }
    3918             : 
    3919           0 :   ResultHelper helper(mRequest, mTransaction, mCursor);
    3920           0 :   DispatchSuccessEvent(&helper);
    3921           0 : }
    3922             : 
    3923             : void
    3924           0 : BackgroundCursorChild::ActorDestroy(ActorDestroyReason aWhy)
    3925             : {
    3926           0 :   AssertIsOnOwningThread();
    3927           0 :   MOZ_ASSERT_IF(aWhy == Deletion, !mStrongRequest);
    3928           0 :   MOZ_ASSERT_IF(aWhy == Deletion, !mStrongCursor);
    3929             : 
    3930           0 :   MaybeCollectGarbageOnIPCMessage();
    3931             : 
    3932           0 :   if (mStrongRequest && !mStrongCursor && mTransaction) {
    3933           0 :     mTransaction->OnRequestFinished(/* aActorDestroyedNormally */
    3934           0 :                                     aWhy == Deletion);
    3935             :   }
    3936             : 
    3937           0 :   if (mCursor) {
    3938           0 :     mCursor->ClearBackgroundActor();
    3939             : #ifdef DEBUG
    3940           0 :     mCursor = nullptr;
    3941             : #endif
    3942             :   }
    3943             : 
    3944             : #ifdef DEBUG
    3945           0 :   mRequest = nullptr;
    3946           0 :   mTransaction = nullptr;
    3947           0 :   mObjectStore = nullptr;
    3948           0 :   mIndex = nullptr;
    3949             : #endif
    3950           0 : }
    3951             : 
    3952             : mozilla::ipc::IPCResult
    3953           0 : BackgroundCursorChild::RecvResponse(const CursorResponse& aResponse)
    3954             : {
    3955           0 :   AssertIsOnOwningThread();
    3956           0 :   MOZ_ASSERT(aResponse.type() != CursorResponse::T__None);
    3957           0 :   MOZ_ASSERT(mRequest);
    3958           0 :   MOZ_ASSERT(mTransaction);
    3959           0 :   MOZ_ASSERT_IF(mCursor, mStrongCursor);
    3960           0 :   MOZ_ASSERT_IF(!mCursor, mStrongRequest);
    3961             : 
    3962           0 :   MaybeCollectGarbageOnIPCMessage();
    3963             : 
    3964           0 :   RefPtr<IDBRequest> request;
    3965           0 :   mStrongRequest.swap(request);
    3966             : 
    3967           0 :   RefPtr<IDBCursor> cursor;
    3968           0 :   mStrongCursor.swap(cursor);
    3969             : 
    3970           0 :   switch (aResponse.type()) {
    3971             :     case CursorResponse::Tnsresult:
    3972           0 :       HandleResponse(aResponse.get_nsresult());
    3973           0 :       break;
    3974             : 
    3975             :     case CursorResponse::Tvoid_t:
    3976           0 :       HandleResponse(aResponse.get_void_t());
    3977           0 :       break;
    3978             : 
    3979             :     case CursorResponse::TArrayOfObjectStoreCursorResponse:
    3980           0 :       HandleResponse(aResponse.get_ArrayOfObjectStoreCursorResponse());
    3981           0 :       break;
    3982             : 
    3983             :     case CursorResponse::TObjectStoreKeyCursorResponse:
    3984           0 :       HandleResponse(aResponse.get_ObjectStoreKeyCursorResponse());
    3985           0 :       break;
    3986             : 
    3987             :     case CursorResponse::TIndexCursorResponse:
    3988           0 :       HandleResponse(aResponse.get_IndexCursorResponse());
    3989           0 :       break;
    3990             : 
    3991             :     case CursorResponse::TIndexKeyCursorResponse:
    3992           0 :       HandleResponse(aResponse.get_IndexKeyCursorResponse());
    3993           0 :       break;
    3994             : 
    3995             :     default:
    3996           0 :       MOZ_CRASH("Should never get here!");
    3997             :   }
    3998             : 
    3999           0 :   mTransaction->OnRequestFinished(/* aActorDestroyedNormally */ true);
    4000             : 
    4001           0 :   return IPC_OK();
    4002             : }
    4003             : 
    4004             : NS_IMETHODIMP
    4005           0 : BackgroundCursorChild::
    4006             : DelayedActionRunnable::Run()
    4007             : {
    4008           0 :   MOZ_ASSERT(mActor);
    4009           0 :   mActor->AssertIsOnOwningThread();
    4010           0 :   MOZ_ASSERT(mRequest);
    4011           0 :   MOZ_ASSERT(mActionFunc);
    4012             : 
    4013           0 :   (mActor->*mActionFunc)();
    4014             : 
    4015           0 :   mActor = nullptr;
    4016           0 :   mRequest = nullptr;
    4017             : 
    4018           0 :   return NS_OK;
    4019             : }
    4020             : 
    4021             : nsresult
    4022           0 : BackgroundCursorChild::
    4023             : DelayedActionRunnable::Cancel()
    4024             : {
    4025           0 :   if (NS_WARN_IF(!mActor)) {
    4026           0 :     return NS_ERROR_UNEXPECTED;
    4027             :   }
    4028             : 
    4029             :   // This must always run to clean up our state.
    4030           0 :   Run();
    4031             : 
    4032           0 :   return NS_OK;
    4033             : }
    4034             : 
    4035             : /*******************************************************************************
    4036             :  * BackgroundFileHandleChild
    4037             :  ******************************************************************************/
    4038             : 
    4039           0 : BackgroundFileHandleChild::BackgroundFileHandleChild(IDBFileHandle* aFileHandle)
    4040             :   : mTemporaryStrongFileHandle(aFileHandle)
    4041           0 :   , mFileHandle(aFileHandle)
    4042             : {
    4043           0 :   MOZ_ASSERT(aFileHandle);
    4044           0 :   aFileHandle->AssertIsOnOwningThread();
    4045             : 
    4046           0 :   MOZ_COUNT_CTOR(BackgroundFileHandleChild);
    4047           0 : }
    4048             : 
    4049           0 : BackgroundFileHandleChild::~BackgroundFileHandleChild()
    4050             : {
    4051           0 :   AssertIsOnOwningThread();
    4052             : 
    4053           0 :   MOZ_COUNT_DTOR(BackgroundFileHandleChild);
    4054           0 : }
    4055             : 
    4056             : #ifdef DEBUG
    4057             : 
    4058             : void
    4059           0 : BackgroundFileHandleChild::AssertIsOnOwningThread() const
    4060             : {
    4061           0 :   static_cast<BackgroundMutableFileChild*>(Manager())->AssertIsOnOwningThread();
    4062           0 : }
    4063             : 
    4064             : #endif // DEBUG
    4065             : 
    4066             : void
    4067           0 : BackgroundFileHandleChild::SendDeleteMeInternal()
    4068             : {
    4069           0 :   AssertIsOnOwningThread();
    4070             : 
    4071           0 :   if (mFileHandle) {
    4072           0 :     NoteActorDestroyed();
    4073             : 
    4074           0 :     MOZ_ALWAYS_TRUE(PBackgroundFileHandleChild::SendDeleteMe());
    4075             :   }
    4076           0 : }
    4077             : 
    4078             : void
    4079           0 : BackgroundFileHandleChild::NoteActorDestroyed()
    4080             : {
    4081           0 :   AssertIsOnOwningThread();
    4082           0 :   MOZ_ASSERT_IF(mTemporaryStrongFileHandle, mFileHandle);
    4083             : 
    4084           0 :   if (mFileHandle) {
    4085           0 :     mFileHandle->ClearBackgroundActor();
    4086             : 
    4087             :     // Normally this would be DEBUG-only but NoteActorDestroyed is also called
    4088             :     // from SendDeleteMeInternal. In that case we're going to receive an actual
    4089             :     // ActorDestroy call later and we don't want to touch a dead object.
    4090           0 :     mTemporaryStrongFileHandle = nullptr;
    4091           0 :     mFileHandle = nullptr;
    4092             :   }
    4093           0 : }
    4094             : 
    4095             : void
    4096           0 : BackgroundFileHandleChild::NoteComplete()
    4097             : {
    4098           0 :   AssertIsOnOwningThread();
    4099           0 :   MOZ_ASSERT_IF(mFileHandle, mTemporaryStrongFileHandle);
    4100             : 
    4101           0 :   mTemporaryStrongFileHandle = nullptr;
    4102           0 : }
    4103             : 
    4104             : void
    4105           0 : BackgroundFileHandleChild::ActorDestroy(ActorDestroyReason aWhy)
    4106             : {
    4107           0 :   AssertIsOnOwningThread();
    4108             : 
    4109           0 :   NoteActorDestroyed();
    4110           0 : }
    4111             : 
    4112             : mozilla::ipc::IPCResult
    4113           0 : BackgroundFileHandleChild::RecvComplete(const bool& aAborted)
    4114             : {
    4115           0 :   AssertIsOnOwningThread();
    4116           0 :   MOZ_ASSERT(mFileHandle);
    4117             : 
    4118           0 :   mFileHandle->FireCompleteOrAbortEvents(aAborted);
    4119             : 
    4120           0 :   NoteComplete();
    4121           0 :   return IPC_OK();
    4122             : }
    4123             : 
    4124             : PBackgroundFileRequestChild*
    4125           0 : BackgroundFileHandleChild::AllocPBackgroundFileRequestChild(
    4126             :                                                const FileRequestParams& aParams)
    4127             : {
    4128           0 :   MOZ_CRASH("PBackgroundFileRequestChild actors should be manually "
    4129             :             "constructed!");
    4130             : }
    4131             : 
    4132             : bool
    4133           0 : BackgroundFileHandleChild::DeallocPBackgroundFileRequestChild(
    4134             :                                             PBackgroundFileRequestChild* aActor)
    4135             : {
    4136           0 :   MOZ_ASSERT(aActor);
    4137             : 
    4138           0 :   delete static_cast<BackgroundFileRequestChild*>(aActor);
    4139           0 :   return true;
    4140             : }
    4141             : 
    4142             : /*******************************************************************************
    4143             :  * BackgroundFileRequestChild
    4144             :  ******************************************************************************/
    4145             : 
    4146           0 : BackgroundFileRequestChild::BackgroundFileRequestChild(
    4147           0 :                                                    IDBFileRequest* aFileRequest)
    4148             :   : mFileRequest(aFileRequest)
    4149             :   , mFileHandle(aFileRequest->GetFileHandle())
    4150           0 :   , mActorDestroyed(false)
    4151             : {
    4152           0 :   MOZ_ASSERT(aFileRequest);
    4153           0 :   aFileRequest->AssertIsOnOwningThread();
    4154           0 :   MOZ_ASSERT(mFileHandle);
    4155           0 :   mFileHandle->AssertIsOnOwningThread();
    4156             : 
    4157           0 :   MOZ_COUNT_CTOR(BackgroundFileRequestChild);
    4158           0 : }
    4159             : 
    4160           0 : BackgroundFileRequestChild::~BackgroundFileRequestChild()
    4161             : {
    4162           0 :   AssertIsOnOwningThread();
    4163           0 :   MOZ_ASSERT(!mFileHandle);
    4164             : 
    4165           0 :   MOZ_COUNT_DTOR(BackgroundFileRequestChild);
    4166           0 : }
    4167             : 
    4168             : #ifdef DEBUG
    4169             : 
    4170             : void
    4171           0 : BackgroundFileRequestChild::AssertIsOnOwningThread() const
    4172             : {
    4173           0 :   MOZ_ASSERT(mFileRequest);
    4174           0 :   mFileRequest->AssertIsOnOwningThread();
    4175           0 : }
    4176             : 
    4177             : #endif // DEBUG
    4178             : 
    4179             : void
    4180           0 : BackgroundFileRequestChild::HandleResponse(nsresult aResponse)
    4181             : {
    4182           0 :   AssertIsOnOwningThread();
    4183           0 :   MOZ_ASSERT(NS_FAILED(aResponse));
    4184           0 :   MOZ_ASSERT(NS_ERROR_GET_MODULE(aResponse) == NS_ERROR_MODULE_DOM_FILEHANDLE);
    4185           0 :   MOZ_ASSERT(mFileHandle);
    4186             : 
    4187           0 :   DispatchFileHandleErrorEvent(mFileRequest, aResponse, mFileHandle);
    4188           0 : }
    4189             : 
    4190             : void
    4191           0 : BackgroundFileRequestChild::HandleResponse(
    4192             :                                     const FileRequestGetFileResponse& aResponse)
    4193             : {
    4194           0 :   AssertIsOnOwningThread();
    4195             : 
    4196           0 :   RefPtr<File> file = ConvertActorToFile(mFileHandle, aResponse);
    4197             : 
    4198           0 :   FileHandleResultHelper helper(mFileRequest, mFileHandle, file);
    4199             : 
    4200           0 :   DispatchFileHandleSuccessEvent(&helper);
    4201           0 : }
    4202             : 
    4203             : void
    4204           0 : BackgroundFileRequestChild::HandleResponse(const nsCString& aResponse)
    4205             : {
    4206           0 :   AssertIsOnOwningThread();
    4207             : 
    4208           0 :   FileHandleResultHelper helper(mFileRequest, mFileHandle, &aResponse);
    4209             : 
    4210           0 :   DispatchFileHandleSuccessEvent(&helper);
    4211           0 : }
    4212             : 
    4213             : void
    4214           0 : BackgroundFileRequestChild::HandleResponse(const FileRequestMetadata& aResponse)
    4215             : {
    4216           0 :   AssertIsOnOwningThread();
    4217             : 
    4218           0 :   FileHandleResultHelper helper(mFileRequest, mFileHandle, &aResponse);
    4219             : 
    4220           0 :   DispatchFileHandleSuccessEvent(&helper);
    4221           0 : }
    4222             : 
    4223             : void
    4224           0 : BackgroundFileRequestChild::HandleResponse(JS::Handle<JS::Value> aResponse)
    4225             : {
    4226           0 :   AssertIsOnOwningThread();
    4227             : 
    4228           0 :   FileHandleResultHelper helper(mFileRequest, mFileHandle, &aResponse);
    4229             : 
    4230           0 :   DispatchFileHandleSuccessEvent(&helper);
    4231           0 : }
    4232             : 
    4233             : void
    4234           0 : BackgroundFileRequestChild::ActorDestroy(ActorDestroyReason aWhy)
    4235             : {
    4236           0 :   AssertIsOnOwningThread();
    4237             : 
    4238           0 :   MOZ_ASSERT(!mActorDestroyed);
    4239             : 
    4240           0 :   mActorDestroyed = true;
    4241             : 
    4242           0 :   if (mFileHandle) {
    4243           0 :     mFileHandle->AssertIsOnOwningThread();
    4244             : 
    4245           0 :     mFileHandle->OnRequestFinished(/* aActorDestroyedNormally */
    4246           0 :                                    aWhy == Deletion);
    4247             : 
    4248             : #ifdef DEBUG
    4249           0 :     mFileHandle = nullptr;
    4250             : #endif
    4251             :   }
    4252           0 : }
    4253             : 
    4254             : mozilla::ipc::IPCResult
    4255           0 : BackgroundFileRequestChild::Recv__delete__(const FileRequestResponse& aResponse)
    4256             : {
    4257           0 :   AssertIsOnOwningThread();
    4258           0 :   MOZ_ASSERT(mFileRequest);
    4259           0 :   MOZ_ASSERT(mFileHandle);
    4260             : 
    4261           0 :   if (mFileHandle->IsAborted()) {
    4262             :     // Always handle an "error" with ABORT_ERR if the file handle was aborted,
    4263             :     // even if the request succeeded or failed with another error.
    4264           0 :     HandleResponse(NS_ERROR_DOM_FILEHANDLE_ABORT_ERR);
    4265             :   } else {
    4266           0 :     switch (aResponse.type()) {
    4267             :       case FileRequestResponse::Tnsresult:
    4268           0 :         HandleResponse(aResponse.get_nsresult());
    4269           0 :         break;
    4270             : 
    4271             :       case FileRequestResponse::TFileRequestGetFileResponse:
    4272           0 :         HandleResponse(aResponse.get_FileRequestGetFileResponse());
    4273           0 :         break;
    4274             : 
    4275             :       case FileRequestResponse::TFileRequestReadResponse:
    4276           0 :         HandleResponse(aResponse.get_FileRequestReadResponse().data());
    4277           0 :         break;
    4278             : 
    4279             :       case FileRequestResponse::TFileRequestWriteResponse:
    4280           0 :         HandleResponse(JS::UndefinedHandleValue);
    4281           0 :         break;
    4282             : 
    4283             :       case FileRequestResponse::TFileRequestTruncateResponse:
    4284           0 :         HandleResponse(JS::UndefinedHandleValue);
    4285           0 :         break;
    4286             : 
    4287             :       case FileRequestResponse::TFileRequestFlushResponse:
    4288           0 :         HandleResponse(JS::UndefinedHandleValue);
    4289           0 :         break;
    4290             : 
    4291             :       case FileRequestResponse::TFileRequestGetMetadataResponse:
    4292           0 :         HandleResponse(aResponse.get_FileRequestGetMetadataResponse()
    4293           0 :                                 .metadata());
    4294           0 :         break;
    4295             : 
    4296             :       default:
    4297           0 :         MOZ_CRASH("Unknown response type!");
    4298             :     }
    4299             :   }
    4300             : 
    4301           0 :   mFileHandle->OnRequestFinished(/* aActorDestroyedNormally */ true);
    4302             : 
    4303             :   // Null this out so that we don't try to call OnRequestFinished() again in
    4304             :   // ActorDestroy.
    4305           0 :   mFileHandle = nullptr;
    4306             : 
    4307           0 :   return IPC_OK();
    4308             : }
    4309             : 
    4310             : mozilla::ipc::IPCResult
    4311           0 : BackgroundFileRequestChild::RecvProgress(const uint64_t& aProgress,
    4312             :                                          const uint64_t& aProgressMax)
    4313             : {
    4314           0 :   AssertIsOnOwningThread();
    4315           0 :   MOZ_ASSERT(mFileRequest);
    4316             : 
    4317           0 :   mFileRequest->FireProgressEvent(aProgress, aProgressMax);
    4318             : 
    4319           0 :   return IPC_OK();
    4320             : }
    4321             : 
    4322             : /*******************************************************************************
    4323             :  * BackgroundUtilsChild
    4324             :  ******************************************************************************/
    4325             : 
    4326           0 : BackgroundUtilsChild::BackgroundUtilsChild(IndexedDatabaseManager* aManager)
    4327           0 :   : mManager(aManager)
    4328             : {
    4329           0 :   AssertIsOnOwningThread();
    4330           0 :   MOZ_ASSERT(aManager);
    4331             : 
    4332           0 :   MOZ_COUNT_CTOR(indexedDB::BackgroundUtilsChild);
    4333           0 : }
    4334             : 
    4335           0 : BackgroundUtilsChild::~BackgroundUtilsChild()
    4336             : {
    4337           0 :   MOZ_COUNT_DTOR(indexedDB::BackgroundUtilsChild);
    4338           0 : }
    4339             : 
    4340             : void
    4341           0 : BackgroundUtilsChild::SendDeleteMeInternal()
    4342             : {
    4343           0 :   AssertIsOnOwningThread();
    4344             : 
    4345           0 :   if (mManager) {
    4346           0 :     mManager->ClearBackgroundActor();
    4347           0 :     mManager = nullptr;
    4348             : 
    4349           0 :     MOZ_ALWAYS_TRUE(PBackgroundIndexedDBUtilsChild::SendDeleteMe());
    4350             :   }
    4351           0 : }
    4352             : 
    4353             : void
    4354           0 : BackgroundUtilsChild::ActorDestroy(ActorDestroyReason aWhy)
    4355             : {
    4356           0 :   AssertIsOnOwningThread();
    4357             : 
    4358           0 :   if (mManager) {
    4359           0 :     mManager->ClearBackgroundActor();
    4360             : #ifdef DEBUG
    4361           0 :     mManager = nullptr;
    4362             : #endif
    4363             :   }
    4364           0 : }
    4365             : 
    4366             : } // namespace indexedDB
    4367             : } // namespace dom
    4368             : } // namespace mozilla

Generated by: LCOV version 1.13