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 #ifndef mozilla_dom_indexeddb_actorschild_h__
8 #define mozilla_dom_indexeddb_actorschild_h__
9 
10 #include "js/RootingAPI.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/dom/IDBCursorType.h"
13 #include "mozilla/dom/IDBTransaction.h"
14 #include "mozilla/dom/indexedDB/PBackgroundIDBCursorChild.h"
15 #include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseChild.h"
16 #include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseRequestChild.h"
17 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
18 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryRequestChild.h"
19 #include "mozilla/dom/indexedDB/PBackgroundIDBRequestChild.h"
20 #include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
21 #include "mozilla/dom/indexedDB/PBackgroundIDBTransactionChild.h"
22 #include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionChild.h"
23 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
24 #include "mozilla/dom/PBackgroundFileHandleChild.h"
25 #include "mozilla/dom/PBackgroundFileRequestChild.h"
26 #include "mozilla/dom/PBackgroundMutableFileChild.h"
27 #include "mozilla/InitializedOnce.h"
28 #include "mozilla/UniquePtr.h"
29 #include "nsCOMPtr.h"
30 #include "nsTArray.h"
31 
32 class nsIEventTarget;
33 struct nsID;
34 
35 namespace mozilla {
36 namespace ipc {
37 
38 class BackgroundChildImpl;
39 
40 }  // namespace ipc
41 
42 namespace dom {
43 
44 class IDBCursor;
45 class IDBDatabase;
46 class IDBFactory;
47 class IDBFileHandle;
48 class IDBFileRequest;
49 class IDBMutableFile;
50 class IDBOpenDBRequest;
51 class IDBRequest;
52 class IndexedDatabaseManager;
53 
54 namespace indexedDB {
55 
56 class Key;
57 class PermissionRequestChild;
58 class PermissionRequestParent;
59 class SerializedStructuredCloneReadInfo;
60 struct CloneInfo;
61 
62 }  // namespace indexedDB
63 }  // namespace dom
64 }  // namespace mozilla
65 
MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(mozilla::dom::indexedDB::CloneInfo)66 MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(mozilla::dom::indexedDB::CloneInfo)
67 
68 namespace mozilla {
69 namespace dom {
70 namespace indexedDB {
71 
72 class BackgroundFactoryChild final : public PBackgroundIDBFactoryChild {
73   friend class mozilla::ipc::BackgroundChildImpl;
74   friend IDBFactory;
75 
76   // TODO: This long-lived raw pointer is very suspicious, in particular as it
77   // is used in BackgroundDatabaseChild::EnsureDOMObject to reacquire a strong
78   // reference. What ensures it is kept alive, and why can't we store a strong
79   // reference here?
80   IDBFactory* mFactory;
81 
82  public:
83   NS_INLINE_DECL_REFCOUNTING(BackgroundFactoryChild, override)
84 
85   void AssertIsOnOwningThread() const {
86     NS_ASSERT_OWNINGTHREAD(BackgroundFactoryChild);
87   }
88 
89   IDBFactory& GetDOMObject() const {
90     AssertIsOnOwningThread();
91     MOZ_ASSERT(mFactory);
92     return *mFactory;
93   }
94 
95   bool SendDeleteMe() = delete;
96 
97  private:
98   // Only created by IDBFactory.
99   explicit BackgroundFactoryChild(IDBFactory& aFactory);
100 
101   // Only destroyed by mozilla::ipc::BackgroundChildImpl.
102   ~BackgroundFactoryChild();
103 
104   void SendDeleteMeInternal();
105 
106  public:
107   // IPDL methods are only called by IPDL.
108   void ActorDestroy(ActorDestroyReason aWhy) override;
109 
110   PBackgroundIDBFactoryRequestChild* AllocPBackgroundIDBFactoryRequestChild(
111       const FactoryRequestParams& aParams);
112 
113   bool DeallocPBackgroundIDBFactoryRequestChild(
114       PBackgroundIDBFactoryRequestChild* aActor);
115 
116   PBackgroundIDBDatabaseChild* AllocPBackgroundIDBDatabaseChild(
117       const DatabaseSpec& aSpec, PBackgroundIDBFactoryRequestChild* aRequest);
118 
119   bool DeallocPBackgroundIDBDatabaseChild(PBackgroundIDBDatabaseChild* aActor);
120 
121   mozilla::ipc::IPCResult RecvPBackgroundIDBDatabaseConstructor(
122       PBackgroundIDBDatabaseChild* aActor, const DatabaseSpec& aSpec,
123       PBackgroundIDBFactoryRequestChild* aRequest) override;
124 };
125 
126 class BackgroundDatabaseChild;
127 
128 class BackgroundRequestChildBase {
129  protected:
130   const NotNull<RefPtr<IDBRequest>> mRequest;
131 
132  public:
133   void AssertIsOnOwningThread() const
134 #ifdef DEBUG
135       ;
136 #else
137   {
138   }
139 #endif
140 
141  protected:
142   explicit BackgroundRequestChildBase(
143       MovingNotNull<RefPtr<IDBRequest>> aRequest);
144 
145   virtual ~BackgroundRequestChildBase();
146 };
147 
148 class BackgroundFactoryRequestChild final
149     : public BackgroundRequestChildBase,
150       public PBackgroundIDBFactoryRequestChild {
151   typedef mozilla::dom::quota::PersistenceType PersistenceType;
152 
153   friend IDBFactory;
154   friend class BackgroundFactoryChild;
155   friend class BackgroundDatabaseChild;
156   friend class PermissionRequestChild;
157   friend class PermissionRequestParent;
158 
159   const SafeRefPtr<IDBFactory> mFactory;
160 
161   // Normally when opening of a database is successful, we receive a database
162   // actor in request response, so we can use it to call ReleaseDOMObject()
163   // which clears temporary strong reference to IDBDatabase.
164   // However, when there's an error, we don't receive a database actor and
165   // IDBRequest::mTransaction is already cleared (must be). So the only way how
166   // to call ReleaseDOMObject() is to have a back-reference to database actor.
167   // This creates a weak ref cycle between
168   // BackgroundFactoryRequestChild (using mDatabaseActor member) and
169   // BackgroundDatabaseChild actor (using mOpenRequestActor member).
170   // mDatabaseActor is set in EnsureDOMObject() and cleared in
171   // ReleaseDOMObject().
172   BackgroundDatabaseChild* mDatabaseActor;
173 
174   const uint64_t mRequestedVersion;
175   const bool mIsDeleteOp;
176 
177  public:
178   NotNull<IDBOpenDBRequest*> GetOpenDBRequest() const;
179 
180  private:
181   // Only created by IDBFactory.
182   BackgroundFactoryRequestChild(
183       SafeRefPtr<IDBFactory> aFactory,
184       MovingNotNull<RefPtr<IDBOpenDBRequest>> aOpenRequest, bool aIsDeleteOp,
185       uint64_t aRequestedVersion);
186 
187   // Only destroyed by BackgroundFactoryChild.
188   ~BackgroundFactoryRequestChild();
189 
190   void SetDatabaseActor(BackgroundDatabaseChild* aActor);
191 
192   bool HandleResponse(nsresult aResponse);
193 
194   bool HandleResponse(const OpenDatabaseRequestResponse& aResponse);
195 
196   bool HandleResponse(const DeleteDatabaseRequestResponse& aResponse);
197 
198  public:
199   // IPDL methods are only called by IPDL.
200   void ActorDestroy(ActorDestroyReason aWhy) override;
201 
202   mozilla::ipc::IPCResult Recv__delete__(
203       const FactoryRequestResponse& aResponse);
204 
205   mozilla::ipc::IPCResult RecvPermissionChallenge(
206       PrincipalInfo&& aPrincipalInfo);
207 
208   mozilla::ipc::IPCResult RecvBlocked(uint64_t aCurrentVersion);
209 };
210 
211 class BackgroundDatabaseChild final : public PBackgroundIDBDatabaseChild {
212   friend class BackgroundFactoryChild;
213   friend class BackgroundFactoryRequestChild;
214   friend IDBDatabase;
215 
216   UniquePtr<DatabaseSpec> mSpec;
217   RefPtr<IDBDatabase> mTemporaryStrongDatabase;
218   BackgroundFactoryRequestChild* mOpenRequestActor;
219   IDBDatabase* mDatabase;
220 
221  public:
222   void AssertIsOnOwningThread() const
223 #ifdef DEBUG
224       ;
225 #else
226   {
227   }
228 #endif
229 
230   const DatabaseSpec* Spec() const {
231     AssertIsOnOwningThread();
232     return mSpec.get();
233   }
234 
235   IDBDatabase* GetDOMObject() const {
236     AssertIsOnOwningThread();
237     return mDatabase;
238   }
239 
240   bool SendDeleteMe() = delete;
241 
242  private:
243   // Only constructed by BackgroundFactoryChild.
244   BackgroundDatabaseChild(const DatabaseSpec& aSpec,
245                           BackgroundFactoryRequestChild* aOpenRequest);
246 
247   // Only destroyed by BackgroundFactoryChild.
248   ~BackgroundDatabaseChild();
249 
250   void SendDeleteMeInternal();
251 
252   [[nodiscard]] bool EnsureDOMObject();
253 
254   void ReleaseDOMObject();
255 
256  public:
257   // IPDL methods are only called by IPDL.
258   void ActorDestroy(ActorDestroyReason aWhy) override;
259 
260   PBackgroundIDBDatabaseFileChild* AllocPBackgroundIDBDatabaseFileChild(
261       const IPCBlob& aIPCBlob);
262 
263   bool DeallocPBackgroundIDBDatabaseFileChild(
264       PBackgroundIDBDatabaseFileChild* aActor);
265 
266   PBackgroundIDBDatabaseRequestChild* AllocPBackgroundIDBDatabaseRequestChild(
267       const DatabaseRequestParams& aParams);
268 
269   bool DeallocPBackgroundIDBDatabaseRequestChild(
270       PBackgroundIDBDatabaseRequestChild* aActor);
271 
272   already_AddRefed<PBackgroundIDBVersionChangeTransactionChild>
273   AllocPBackgroundIDBVersionChangeTransactionChild(uint64_t aCurrentVersion,
274                                                    uint64_t aRequestedVersion,
275                                                    int64_t aNextObjectStoreId,
276                                                    int64_t aNextIndexId);
277 
278   mozilla::ipc::IPCResult RecvPBackgroundIDBVersionChangeTransactionConstructor(
279       PBackgroundIDBVersionChangeTransactionChild* aActor,
280       const uint64_t& aCurrentVersion, const uint64_t& aRequestedVersion,
281       const int64_t& aNextObjectStoreId, const int64_t& aNextIndexId) override;
282 
283   PBackgroundMutableFileChild* AllocPBackgroundMutableFileChild(
284       const nsString& aName, const nsString& aType);
285 
286   bool DeallocPBackgroundMutableFileChild(PBackgroundMutableFileChild* aActor);
287 
288   mozilla::ipc::IPCResult RecvVersionChange(uint64_t aOldVersion,
289                                             Maybe<uint64_t> aNewVersion);
290 
291   mozilla::ipc::IPCResult RecvInvalidate();
292 
293   mozilla::ipc::IPCResult RecvCloseAfterInvalidationComplete();
294 };
295 
296 class BackgroundDatabaseRequestChild final
297     : public BackgroundRequestChildBase,
298       public PBackgroundIDBDatabaseRequestChild {
299   friend class BackgroundDatabaseChild;
300   friend IDBDatabase;
301 
302   RefPtr<IDBDatabase> mDatabase;
303 
304  private:
305   // Only created by IDBDatabase.
306   BackgroundDatabaseRequestChild(IDBDatabase* aDatabase,
307                                  MovingNotNull<RefPtr<IDBRequest>> aRequest);
308 
309   // Only destroyed by BackgroundDatabaseChild.
310   ~BackgroundDatabaseRequestChild();
311 
312   bool HandleResponse(nsresult aResponse);
313 
314   bool HandleResponse(const CreateFileRequestResponse& aResponse);
315 
316  public:
317   // IPDL methods are only called by IPDL.
318   mozilla::ipc::IPCResult Recv__delete__(
319       const DatabaseRequestResponse& aResponse);
320 };
321 
322 class BackgroundVersionChangeTransactionChild;
323 
324 class BackgroundTransactionBase {
325   friend class BackgroundVersionChangeTransactionChild;
326 
327   // mTemporaryStrongTransaction is strong and is only valid until the end of
328   // NoteComplete() member function or until the NoteActorDestroyed() member
329   // function is called.
330   SafeRefPtr<IDBTransaction> mTemporaryStrongTransaction;
331 
332  protected:
333   // mTransaction is weak and is valid until the NoteActorDestroyed() member
334   // function is called.
335   IDBTransaction* mTransaction = nullptr;
336 
337  public:
338 #ifdef DEBUG
339   virtual void AssertIsOnOwningThread() const = 0;
340 #else
341   void AssertIsOnOwningThread() const {}
342 #endif
343 
344   IDBTransaction* GetDOMObject() const {
345     AssertIsOnOwningThread();
346     return mTransaction;
347   }
348 
349  protected:
350   MOZ_COUNTED_DEFAULT_CTOR(BackgroundTransactionBase);
351 
352   explicit BackgroundTransactionBase(SafeRefPtr<IDBTransaction> aTransaction);
353 
354   MOZ_COUNTED_DTOR_VIRTUAL(BackgroundTransactionBase);
355 
356   void NoteActorDestroyed();
357 
358   void NoteComplete();
359 
360  private:
361   // Only called by BackgroundVersionChangeTransactionChild.
362   void SetDOMTransaction(SafeRefPtr<IDBTransaction> aTransaction);
363 };
364 
365 class BackgroundTransactionChild final : public BackgroundTransactionBase,
366                                          public PBackgroundIDBTransactionChild {
367   friend class BackgroundDatabaseChild;
368   friend IDBDatabase;
369 
370  public:
371   NS_INLINE_DECL_REFCOUNTING(BackgroundTransactionChild, override)
372 
373 #ifdef DEBUG
374   void AssertIsOnOwningThread() const override;
375 #endif
376 
377   void SendDeleteMeInternal();
378 
379   bool SendDeleteMe() = delete;
380 
381  private:
382   // Only created by IDBDatabase.
383   explicit BackgroundTransactionChild(SafeRefPtr<IDBTransaction> aTransaction);
384 
385   // Only destroyed by BackgroundDatabaseChild.
386   ~BackgroundTransactionChild();
387 
388  public:
389   // IPDL methods are only called by IPDL.
390   void ActorDestroy(ActorDestroyReason aWhy) override;
391 
392   mozilla::ipc::IPCResult RecvComplete(nsresult aResult);
393 
394   PBackgroundIDBRequestChild* AllocPBackgroundIDBRequestChild(
395       const RequestParams& aParams);
396 
397   bool DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor);
398 
399   PBackgroundIDBCursorChild* AllocPBackgroundIDBCursorChild(
400       const OpenCursorParams& aParams);
401 
402   bool DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor);
403 };
404 
405 class BackgroundVersionChangeTransactionChild final
406     : public BackgroundTransactionBase,
407       public PBackgroundIDBVersionChangeTransactionChild {
408   friend class BackgroundDatabaseChild;
409 
410   IDBOpenDBRequest* mOpenDBRequest;
411 
412  public:
413   NS_INLINE_DECL_REFCOUNTING(BackgroundVersionChangeTransactionChild, override)
414 
415 #ifdef DEBUG
416   void AssertIsOnOwningThread() const override;
417 #endif
418 
419   void SendDeleteMeInternal(bool aFailedConstructor);
420 
421   bool SendDeleteMe() = delete;
422 
423  private:
424   // Only created by BackgroundDatabaseChild.
425   explicit BackgroundVersionChangeTransactionChild(
426       IDBOpenDBRequest* aOpenDBRequest);
427 
428   // Only destroyed by BackgroundDatabaseChild.
429   ~BackgroundVersionChangeTransactionChild();
430 
431   // Only called by BackgroundDatabaseChild.
432   using BackgroundTransactionBase::SetDOMTransaction;
433 
434  public:
435   // IPDL methods are only called by IPDL.
436   void ActorDestroy(ActorDestroyReason aWhy) override;
437 
438   mozilla::ipc::IPCResult RecvComplete(nsresult aResult);
439 
440   PBackgroundIDBRequestChild* AllocPBackgroundIDBRequestChild(
441       const RequestParams& aParams);
442 
443   bool DeallocPBackgroundIDBRequestChild(PBackgroundIDBRequestChild* aActor);
444 
445   PBackgroundIDBCursorChild* AllocPBackgroundIDBCursorChild(
446       const OpenCursorParams& aParams);
447 
448   bool DeallocPBackgroundIDBCursorChild(PBackgroundIDBCursorChild* aActor);
449 };
450 
451 class BackgroundMutableFileChild final : public PBackgroundMutableFileChild {
452   friend class BackgroundDatabaseChild;
453   friend IDBMutableFile;
454 
455   RefPtr<IDBMutableFile> mTemporaryStrongMutableFile;
456   IDBMutableFile* mMutableFile;
457   nsString mName;
458   nsString mType;
459 
460  public:
461   void AssertIsOnOwningThread() const
462 #ifdef DEBUG
463       ;
464 #else
465   {
466   }
467 #endif
468 
469   void EnsureDOMObject();
470 
471   IDBMutableFile* GetDOMObject() const {
472     AssertIsOnOwningThread();
473     return mMutableFile;
474   }
475 
476   void ReleaseDOMObject();
477 
478   bool SendDeleteMe() = delete;
479 
480  private:
481   // Only constructed by BackgroundDatabaseChild.
482   BackgroundMutableFileChild(const nsAString& aName, const nsAString& aType);
483 
484   // Only destroyed by BackgroundDatabaseChild.
485   ~BackgroundMutableFileChild();
486 
487   void SendDeleteMeInternal();
488 
489  public:
490   // IPDL methods are only called by IPDL.
491   void ActorDestroy(ActorDestroyReason aWhy) override;
492 
493   PBackgroundFileHandleChild* AllocPBackgroundFileHandleChild(
494       const FileMode& aMode);
495 
496   bool DeallocPBackgroundFileHandleChild(PBackgroundFileHandleChild* aActor);
497 };
498 
499 class BackgroundRequestChild final : public BackgroundRequestChildBase,
500                                      public PBackgroundIDBRequestChild {
501   friend class BackgroundTransactionChild;
502   friend class BackgroundVersionChangeTransactionChild;
503   friend struct CloneInfo;
504   friend IDBTransaction;
505 
506   class PreprocessHelper;
507 
508   SafeRefPtr<IDBTransaction> mTransaction;
509   nsTArray<CloneInfo> mCloneInfos;
510   uint32_t mRunningPreprocessHelpers;
511   uint32_t mCurrentCloneDataIndex;
512   nsresult mPreprocessResultCode;
513   bool mGetAll;
514 
515  private:
516   // Only created by IDBTransaction.
517   explicit BackgroundRequestChild(MovingNotNull<RefPtr<IDBRequest>> aRequest);
518 
519   // Only destroyed by BackgroundTransactionChild or
520   // BackgroundVersionChangeTransactionChild.
521   ~BackgroundRequestChild();
522 
523   void MaybeSendContinue();
524 
525   void OnPreprocessFinished(uint32_t aCloneDataIndex,
526                             UniquePtr<JSStructuredCloneData> aCloneData);
527 
528   void OnPreprocessFailed(uint32_t aCloneDataIndex, nsresult aErrorCode);
529 
530   UniquePtr<JSStructuredCloneData> GetNextCloneData();
531 
532   void HandleResponse(nsresult aResponse);
533 
534   void HandleResponse(const Key& aResponse);
535 
536   void HandleResponse(const nsTArray<Key>& aResponse);
537 
538   void HandleResponse(SerializedStructuredCloneReadInfo&& aResponse);
539 
540   void HandleResponse(nsTArray<SerializedStructuredCloneReadInfo>&& aResponse);
541 
542   void HandleResponse(JS::Handle<JS::Value> aResponse);
543 
544   void HandleResponse(uint64_t aResponse);
545 
546   nsresult HandlePreprocess(const PreprocessInfo& aPreprocessInfo);
547 
548   nsresult HandlePreprocess(const nsTArray<PreprocessInfo>& aPreprocessInfos);
549 
550   nsresult HandlePreprocessInternal(
551       const nsTArray<PreprocessInfo>& aPreprocessInfos);
552 
553   SafeRefPtr<IDBTransaction> AcquireTransaction() const {
554     return mTransaction.clonePtr();
555   }
556 
557  public:
558   // IPDL methods are only called by IPDL.
559   void ActorDestroy(ActorDestroyReason aWhy) override;
560 
561   mozilla::ipc::IPCResult Recv__delete__(RequestResponse&& aResponse);
562 
563   mozilla::ipc::IPCResult RecvPreprocess(const PreprocessParams& aParams);
564 };
565 
566 struct CloneInfo {
567   RefPtr<BackgroundRequestChild::PreprocessHelper> mPreprocessHelper;
568   UniquePtr<JSStructuredCloneData> mCloneData;
569 };
570 
571 class BackgroundCursorChildBase
572     : public PBackgroundIDBCursorChild,
573       public SafeRefCounted<BackgroundCursorChildBase> {
574  private:
575   NS_DECL_OWNINGTHREAD
576 
577  public:
578   MOZ_DECLARE_REFCOUNTED_TYPENAME(
579       mozilla::dom::indexedDB::BackgroundCursorChildBase)
580   MOZ_INLINE_DECL_SAFEREFCOUNTING_INHERITED(BackgroundCursorChildBase,
581                                             SafeRefCounted)
582 
583  protected:
584   ~BackgroundCursorChildBase();
585 
586   InitializedOnce<const NotNull<IDBRequest*>> mRequest;
587   Maybe<IDBTransaction&> mTransaction;
588 
589   // These are only set while a request is in progress.
590   RefPtr<IDBRequest> mStrongRequest;
591   RefPtr<IDBCursor> mStrongCursor;
592 
593   const Direction mDirection;
594 
595   BackgroundCursorChildBase(NotNull<IDBRequest*> aRequest,
596                             Direction aDirection);
597 
598   void HandleResponse(nsresult aResponse);
599 
600  public:
601   void AssertIsOnOwningThread() const {
602     NS_ASSERT_OWNINGTHREAD(BackgroundCursorChildBase);
603   }
604 
605   MovingNotNull<RefPtr<IDBRequest>> AcquireRequest() const;
606 
607   NotNull<IDBRequest*> GetRequest() const {
608     AssertIsOnOwningThread();
609 
610     return *mRequest;
611   }
612 
613   Direction GetDirection() const {
614     AssertIsOnOwningThread();
615 
616     return mDirection;
617   }
618 
619   virtual void SendDeleteMeInternal() = 0;
620 
621   virtual mozilla::ipc::IPCResult RecvResponse(CursorResponse&& aResponse) = 0;
622 };
623 
624 template <IDBCursorType CursorType>
625 class BackgroundCursorChild final : public BackgroundCursorChildBase {
626  public:
627   using SourceType = CursorSourceType<CursorType>;
628   using ResponseType = typename CursorTypeTraits<CursorType>::ResponseType;
629 
630  private:
631   friend class BackgroundTransactionChild;
632   friend class BackgroundVersionChangeTransactionChild;
633 
634   InitializedOnce<const NotNull<SourceType*>> mSource;
635   IDBCursorImpl<CursorType>* mCursor;
636 
637   std::deque<CursorData<CursorType>> mCachedResponses, mDelayedResponses;
638   bool mInFlightResponseInvalidationNeeded;
639 
640  public:
641   BackgroundCursorChild(NotNull<IDBRequest*> aRequest, SourceType* aSource,
642                         Direction aDirection);
643 
644   void SendContinueInternal(const CursorRequestParams& aParams,
645                             const CursorData<CursorType>& aCurrentData);
646 
647   void InvalidateCachedResponses();
648 
649   template <typename Condition>
650   void DiscardCachedResponses(const Condition& aConditionFunc);
651 
652   SourceType* GetSource() const {
653     AssertIsOnOwningThread();
654 
655     return *mSource;
656   }
657 
658   void SendDeleteMeInternal() final;
659 
660  private:
661   // Only destroyed by BackgroundTransactionChild or
662   // BackgroundVersionChangeTransactionChild.
663   ~BackgroundCursorChild();
664 
665   void CompleteContinueRequestFromCache();
666 
667   using BackgroundCursorChildBase::HandleResponse;
668 
669   void HandleResponse(const void_t& aResponse);
670 
671   void HandleResponse(nsTArray<ResponseType>&& aResponses);
672 
673   template <typename Func>
674   void HandleMultipleCursorResponses(nsTArray<ResponseType>&& aResponses,
675                                      const Func& aHandleRecord);
676 
677   template <typename... Args>
678   [[nodiscard]] RefPtr<IDBCursor> HandleIndividualCursorResponse(
679       bool aUseAsCurrentResult, Args&&... aArgs);
680 
681   SafeRefPtr<BackgroundCursorChild> SafeRefPtrFromThis();
682 
683  public:
684   // IPDL methods are only called by IPDL.
685   void ActorDestroy(ActorDestroyReason aWhy) override;
686 
687   mozilla::ipc::IPCResult RecvResponse(CursorResponse&& aResponse) override;
688 
689   // Force callers to use SendContinueInternal.
690   bool SendContinue(const CursorRequestParams& aParams, const Key& aCurrentKey,
691                     const Key& aCurrentObjectStoreKey) = delete;
692 
693   bool SendDeleteMe() = delete;
694 };
695 
696 class BackgroundFileHandleChild : public PBackgroundFileHandleChild {
697   friend class BackgroundMutableFileChild;
698   friend IDBMutableFile;
699 
700   // mTemporaryStrongFileHandle is strong and is only valid until the end of
701   // NoteComplete() member function or until the NoteActorDestroyed() member
702   // function is called.
703   RefPtr<IDBFileHandle> mTemporaryStrongFileHandle;
704 
705   // mFileHandle is weak and is valid until the NoteActorDestroyed() member
706   // function is called.
707   IDBFileHandle* mFileHandle;
708 
709  public:
710   void AssertIsOnOwningThread() const
711 #ifdef DEBUG
712       ;
713 #else
714   {
715   }
716 #endif
717 
718   void SendDeleteMeInternal();
719 
720   bool SendDeleteMe() = delete;
721 
722  private:
723   // Only created by IDBMutableFile.
724   explicit BackgroundFileHandleChild(IDBFileHandle* aFileHandle);
725 
726   ~BackgroundFileHandleChild();
727 
728   void NoteActorDestroyed();
729 
730   void NoteComplete();
731 
732  public:
733   // IPDL methods are only called by IPDL.
734   void ActorDestroy(ActorDestroyReason aWhy) override;
735 
736   mozilla::ipc::IPCResult RecvComplete(bool aAborted);
737 
738   PBackgroundFileRequestChild* AllocPBackgroundFileRequestChild(
739       const FileRequestParams& aParams);
740 
741   bool DeallocPBackgroundFileRequestChild(PBackgroundFileRequestChild* aActor);
742 };
743 
744 class BackgroundFileRequestChild final : public PBackgroundFileRequestChild {
745   friend class BackgroundFileHandleChild;
746   friend IDBFileHandle;
747 
748   RefPtr<IDBFileRequest> mFileRequest;
749   RefPtr<IDBFileHandle> mFileHandle;
750   bool mActorDestroyed;
751 
752  public:
753   void AssertIsOnOwningThread() const
754 #ifdef DEBUG
755       ;
756 #else
757   {
758   }
759 #endif
760 
761  private:
762   // Only created by IDBFileHandle.
763   explicit BackgroundFileRequestChild(IDBFileRequest* aFileRequest);
764 
765   // Only destroyed by BackgroundFileHandleChild.
766   ~BackgroundFileRequestChild();
767 
768   void HandleResponse(nsresult aResponse);
769 
770   void HandleResponse(const nsCString& aResponse);
771 
772   void HandleResponse(const FileRequestMetadata& aResponse);
773 
774   void HandleResponse(JS::Handle<JS::Value> aResponse);
775 
776  public:
777   // IPDL methods are only called by IPDL.
778   void ActorDestroy(ActorDestroyReason aWhy) override;
779 
780   mozilla::ipc::IPCResult Recv__delete__(const FileRequestResponse& aResponse);
781 
782   mozilla::ipc::IPCResult RecvProgress(uint64_t aProgress,
783                                        uint64_t aProgressMax);
784 };
785 
786 class BackgroundUtilsChild final : public PBackgroundIndexedDBUtilsChild {
787   friend class mozilla::ipc::BackgroundChildImpl;
788   friend IndexedDatabaseManager;
789 
790   IndexedDatabaseManager* mManager;
791 
792   NS_DECL_OWNINGTHREAD
793 
794  public:
795   void AssertIsOnOwningThread() const {
796     NS_ASSERT_OWNINGTHREAD(BackgroundUtilsChild);
797   }
798 
799   bool SendDeleteMe() = delete;
800 
801  private:
802   // Only created by IndexedDatabaseManager.
803   explicit BackgroundUtilsChild(IndexedDatabaseManager* aManager);
804 
805   // Only destroyed by mozilla::ipc::BackgroundChildImpl.
806   ~BackgroundUtilsChild();
807 
808   void SendDeleteMeInternal();
809 
810  public:
811   // IPDL methods are only called by IPDL.
812   void ActorDestroy(ActorDestroyReason aWhy) override;
813 };
814 
815 }  // namespace indexedDB
816 }  // namespace dom
817 }  // namespace mozilla
818 
819 #endif  // mozilla_dom_indexeddb_actorschild_h__
820