Backed out 8 changesets (bug 1588241) for wpt leaks on ChannelEvent/ChannelEventQueue. CLOSED TREE
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Wed, 13 Nov 2019 09:24:22 +0200
changeset 501705 2f19e7b646e0a52fa855b75c868f0a3f3a990ad3
parent 501704 c9769928194867af402830fae75ce4290289f9c1
child 501706 10992479f249f70907e688b5c5622deb042d9ba7
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1588241
milestone72.0a1
backs out6a4727c44078f7eca99f39b72a6f8eab2752c3f0
125430c4316a188db6ce5b50da3ffdd99c4fc5aa
449606f22baf89dbd2ddd4fc537219c13907bd11
c9a6203582acc7285034ab684d1f844e2ddda108
48362412c9d583393fc81a551543499b4bf31039
a21cd1c41c6cbea911d0039764bdab6bc523cbf5
8d2cf0fc6b9bd03e2a34b6cefc0bd3be36bd06c0
17e7f137067f89c0d82cada3af77b1bc5161c547
first release with
nightly linux32
2f19e7b646e0 / 72.0a1 / 20191113095525 / files
nightly linux64
2f19e7b646e0 / 72.0a1 / 20191113095525 / files
nightly mac
2f19e7b646e0 / 72.0a1 / 20191113095525 / files
nightly win32
2f19e7b646e0 / 72.0a1 / 20191113095525 / files
nightly win64
2f19e7b646e0 / 72.0a1 / 20191113095525 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 8 changesets (bug 1588241) for wpt leaks on ChannelEvent/ChannelEventQueue. CLOSED TREE Backed out changeset 6a4727c44078 (bug 1588241) Backed out changeset 125430c4316a (bug 1588241) Backed out changeset 449606f22baf (bug 1588241) Backed out changeset c9a6203582ac (bug 1588241) Backed out changeset 48362412c9d5 (bug 1588241) Backed out changeset a21cd1c41c6c (bug 1588241) Backed out changeset 8d2cf0fc6b9b (bug 1588241) Backed out changeset 17e7f137067f (bug 1588241)
browser/base/content/test/trackingUI/browser.ini
netwerk/ipc/ChannelEventQueue.cpp
netwerk/ipc/ChannelEventQueue.h
netwerk/ipc/DocumentChannelChild.cpp
netwerk/ipc/DocumentChannelChild.h
netwerk/ipc/DocumentChannelParent.cpp
netwerk/ipc/DocumentChannelParent.h
netwerk/ipc/PDocumentChannel.ipdl
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelChild.h
netwerk/protocol/http/HttpBackgroundChannelChild.cpp
netwerk/protocol/http/HttpBackgroundChannelChild.h
netwerk/protocol/http/HttpBackgroundChannelParent.cpp
netwerk/protocol/http/HttpBackgroundChannelParent.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/HttpChannelParent.cpp
netwerk/protocol/http/PHttpBackgroundChannel.ipdl
netwerk/protocol/http/PHttpChannel.ipdl
toolkit/components/antitracking/test/browser/browser.ini
--- a/browser/base/content/test/trackingUI/browser.ini
+++ b/browser/base/content/test/trackingUI/browser.ini
@@ -8,53 +8,52 @@ support-files =
   cookieSetterPage.html
   cookieServer.sjs
   embeddedPage.html
   trackingAPI.js
   trackingPage.html
 
 [browser_trackingUI_3.js]
 [browser_trackingUI_animation.js]
-skip-if = fission # See bug 1580752.
+skip-if = fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_animation_2.js]
-skip-if = fission # See bug 1580752.
+skip-if = fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_appMenu.js]
 [browser_trackingUI_background_tabs.js]
-skip-if = fission # See bug 1580752.
+skip-if = fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_categories.js]
 [browser_trackingUI_cookies_subview.js]
-skip-if = fission # See bug 1580752.
 [browser_trackingUI_cryptominers.js]
 skip-if =
   fission && debug || # Causing crashes [@ mozilla::net::HttpChannelChild::DoOnStartRequest(nsIRequest*, nsISupports*)]
-  fission # See bug 1580752.
+  fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_fetch.js]
 support-files =
   file_trackingUI_fetch.html
   file_trackingUI_fetch.js
   file_trackingUI_fetch.js^headers^
 [browser_trackingUI_fingerprinters.js]
-skip-if = fission # See bug 1580752.
+skip-if = fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_open_preferences.js]
-skip-if = fission # See bug 1580752.
+skip-if = fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_pbmode_exceptions.js]
 skip-if = fission # Crashes: @ mozilla::dom::BrowserBridgeParent::RecvShow(mozilla::gfx::IntSizeTyped<mozilla::ScreenPixel> const&, bool const&, nsSizeMode const&)
 [browser_trackingUI_report_breakage.js]
 skip-if = fission || debug || asan # Bug 1546797
 [browser_trackingUI_socialtracking.js]
 skip-if =
   fission && debug || # Crashes: @ mozilla::net::HttpChannelChild::DoOnStartRequest(nsIRequest*, nsISupports*)
-  fission # See bug 1580752.
+  fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_shield_visibility.js]
 [browser_trackingUI_state.js]
 skip-if = serviceworker_e10s || fission # see https://bugzilla.mozilla.org/show_bug.cgi?id=1511303#c1 #Bug 1574939
 [browser_trackingUI_state_reset.js]
 skip-if =
   fission && debug || #Bug 1574939
-  fission # See bug 1580752.
+  fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_telemetry.js]
 skip-if =
   fission && debug || #Bug 1574939
-  fission # See bug 1580752.
+  fission # Times out under Fission with DocumentChannel enabled.
 [browser_trackingUI_trackers_subview.js]
 skip-if =
   fission && debug || #Bug 1574939
-  fission # See bug 1580752.
+  fission # Times out under Fission with DocumentChannel enabled.
--- a/netwerk/ipc/ChannelEventQueue.cpp
+++ b/netwerk/ipc/ChannelEventQueue.cpp
@@ -70,17 +70,17 @@ void ChannelEventQueue::FlushQueue() {
       MOZ_DIAGNOSTIC_ASSERT(false);
       isCurrentThread = true;
     }
 
     if (!isCurrentThread) {
       // Next event needs to run on another thread. Put it back to
       // the front of the queue can try resume on that thread.
       Suspend();
-      PrependEvent(std::move(event));
+      PrependEvent(event);
 
       needResumeOnOtherThread = true;
       {
         MutexAutoLock lock(mMutex);
         MOZ_ASSERT(mFlushing);
         mFlushing = false;
         MOZ_ASSERT(!mEventQueue.IsEmpty());
       }
--- a/netwerk/ipc/ChannelEventQueue.h
+++ b/netwerk/ipc/ChannelEventQueue.h
@@ -65,46 +65,16 @@ class NeckoTargetChannelEvent : public C
 
     return mChild->GetNeckoTarget();
   }
 
  protected:
   T* mChild;
 };
 
-class ChannelFunctionEvent : public ChannelEvent {
- public:
-  ChannelFunctionEvent(
-      std::function<already_AddRefed<nsIEventTarget>()>&& aGetEventTarget,
-      std::function<void()>&& aCallback)
-      : mGetEventTarget(std::move(aGetEventTarget)),
-        mCallback(std::move(aCallback)) {}
-
-  void Run() override { mCallback(); }
-  already_AddRefed<nsIEventTarget> GetEventTarget() override {
-    return mGetEventTarget();
-  }
-
- private:
-  const std::function<already_AddRefed<nsIEventTarget>()> mGetEventTarget;
-  const std::function<void()> mCallback;
-};
-
-class NeckoTargetChannelFunctionEvent : public ChannelFunctionEvent {
- public:
-  template <typename T>
-  NeckoTargetChannelFunctionEvent(T* aChild, std::function<void()>&& aCallback)
-      : ChannelFunctionEvent(
-            [child = RefPtr<T>(aChild)]() {
-              MOZ_ASSERT(child);
-              return child->GetNeckoTarget();
-            },
-            std::move(aCallback)) {}
-};
-
 // Workaround for Necko re-entrancy dangers. We buffer IPDL messages in a
 // queue if still dispatching previous one(s) to listeners/observers.
 // Otherwise synchronous XMLHttpRequests and/or other code that spins the
 // event loop (ex: IPDL rpc) could cause listener->OnDataAvailable (for
 // instance) to be dispatched and called before mListener->OnStartRequest has
 // completed.
 
 class ChannelEventQueue final {
@@ -127,17 +97,17 @@ class ChannelEventQueue final {
   //
   // @param aCallback - the ChannelEvent
   // @param aAssertionWhenNotQueued - this optional param will be used in an
   //   assertion when the event is executed directly.
   inline void RunOrEnqueue(ChannelEvent* aCallback,
                            bool aAssertionWhenNotQueued = false);
 
   // Append ChannelEvent in front of the event queue.
-  inline nsresult PrependEvent(UniquePtr<ChannelEvent>&& aEvent);
+  inline nsresult PrependEvent(UniquePtr<ChannelEvent>& aEvent);
   inline nsresult PrependEvents(nsTArray<UniquePtr<ChannelEvent>>& aEvents);
 
   // After StartForcedQueueing is called, RunOrEnqueue() will start enqueuing
   // events that will be run/flushed when EndForcedQueueing is called.
   // - Note: queueing may still be required after EndForcedQueueing() (if the
   //   queue is suspended, etc):  always call RunOrEnqueue() to avoid race
   //   conditions.
   inline void StartForcedQueueing();
@@ -256,17 +226,17 @@ inline void ChannelEventQueue::EndForced
   }
 
   if (tryFlush) {
     MaybeFlushQueue();
   }
 }
 
 inline nsresult ChannelEventQueue::PrependEvent(
-    UniquePtr<ChannelEvent>&& aEvent) {
+    UniquePtr<ChannelEvent>& aEvent) {
   MutexAutoLock lock(mMutex);
 
   // Prepending event while no queue flush foreseen might cause the following
   // channel events not run. This assertion here guarantee there must be a
   // queue flush, either triggered by Resume or EndForcedQueueing, to execute
   // the added event.
   MOZ_ASSERT(mSuspended || !!mForcedCount);
 
--- a/netwerk/ipc/DocumentChannelChild.cpp
+++ b/netwerk/ipc/DocumentChannelChild.cpp
@@ -38,16 +38,17 @@ NS_INTERFACE_MAP_BEGIN(DocumentChannelCh
     // internally, but doesn't implement the interface. Everything
     // before AsyncOpen should be duplicated in the parent process
     // on the real http channel, but anything trying to QI to nsIHttpChannel
     // after that will be failing and get confused.
     NS_WARNING(
         "Trying to request nsIHttpChannel from DocumentChannelChild, this is "
         "likely broken");
   }
+  NS_INTERFACE_MAP_ENTRY(nsIClassifiedChannel)
   NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
   NS_INTERFACE_MAP_ENTRY_CONCRETE(DocumentChannelChild)
 NS_INTERFACE_MAP_END_INHERITING(nsBaseChannel)
 
 NS_IMPL_ADDREF_INHERITED(DocumentChannelChild, nsBaseChannel)
 NS_IMPL_RELEASE_INHERITED(DocumentChannelChild, nsBaseChannel)
 
 DocumentChannelChild::DocumentChannelChild(
@@ -185,24 +186,41 @@ DocumentChannelChild::AsyncOpen(nsIStrea
 
   mIsPending = true;
   mWasOpened = true;
   mListener = listener;
 
   return NS_OK;
 }
 
+class DocumentFailedAsyncOpenEvent
+    : public NeckoTargetChannelEvent<DocumentChannelChild> {
+ public:
+  DocumentFailedAsyncOpenEvent(DocumentChannelChild* aChild,
+                               nsresult aStatusCode)
+      : NeckoTargetChannelEvent<DocumentChannelChild>(aChild),
+        mStatus(aStatusCode) {}
+
+  void Run() override { mChild->DoFailedAsyncOpen(mStatus); }
+
+ private:
+  nsresult mStatus;
+};
+
 IPCResult DocumentChannelChild::RecvFailedAsyncOpen(
     const nsresult& aStatusCode) {
-  RefPtr<DocumentChannelChild> self = this;
-  mEventQueue->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [self, aStatusCode]() { self->ShutdownListeners(aStatusCode); }));
+  mEventQueue->RunOrEnqueue(
+      new DocumentFailedAsyncOpenEvent(this, aStatusCode));
   return IPC_OK();
 }
 
+void DocumentChannelChild::DoFailedAsyncOpen(const nsresult& aStatusCode) {
+  ShutdownListeners(aStatusCode);
+}
+
 void DocumentChannelChild::ShutdownListeners(nsresult aStatusCode) {
   mStatus = aStatusCode;
 
   nsCOMPtr<nsIStreamListener> l = mListener;
   if (l) {
     l->OnStartRequest(this);
   }
 
@@ -447,16 +465,67 @@ IPCResult DocumentChannelChild::RecvConf
 
   Maybe<nsresult> cancelCode;
   rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, mLoadInfo,
                                          cancelCode);
   aResolve(Tuple<const nsresult&, const Maybe<nsresult>&>(rv, cancelCode));
   return IPC_OK();
 }
 
+IPCResult DocumentChannelChild::RecvNotifyClassificationFlags(
+    const uint32_t& aClassificationFlags, const bool& aIsThirdParty) {
+  if (aIsThirdParty) {
+    mThirdPartyClassificationFlags |= aClassificationFlags;
+  } else {
+    mFirstPartyClassificationFlags |= aClassificationFlags;
+  }
+  return IPC_OK();
+}
+
+IPCResult DocumentChannelChild::RecvNotifyChannelClassifierProtectionDisabled(
+    const uint32_t& aAcceptedReason) {
+  UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
+      this, aAcceptedReason);
+  return IPC_OK();
+}
+
+IPCResult DocumentChannelChild::RecvNotifyCookieAllowed() {
+  AntiTrackingCommon::NotifyBlockingDecision(
+      this, AntiTrackingCommon::BlockingDecision::eAllow, 0);
+  return IPC_OK();
+}
+
+IPCResult DocumentChannelChild::RecvNotifyCookieBlocked(
+    const uint32_t& aRejectedReason) {
+  AntiTrackingCommon::NotifyBlockingDecision(
+      this, AntiTrackingCommon::BlockingDecision::eBlock, aRejectedReason);
+  return IPC_OK();
+}
+
+IPCResult DocumentChannelChild::RecvSetClassifierMatchedInfo(
+    const nsCString& aList, const nsCString& aProvider,
+    const nsCString& aFullHash) {
+  SetMatchedInfo(aList, aProvider, aFullHash);
+  return IPC_OK();
+}
+
+IPCResult DocumentChannelChild::RecvSetClassifierMatchedTrackingInfo(
+    const nsCString& aLists, const nsCString& aFullHash) {
+  nsTArray<nsCString> lists, fullhashes;
+  for (const nsACString& token : aLists.Split(',')) {
+    lists.AppendElement(token);
+  }
+  for (const nsACString& token : aFullHash.Split(',')) {
+    fullhashes.AppendElement(token);
+  }
+
+  SetMatchedTrackingInfo(lists, fullhashes);
+  return IPC_OK();
+}
+
 mozilla::ipc::IPCResult DocumentChannelChild::RecvAttachStreamFilter(
     Endpoint<extensions::PStreamFilterParent>&& aEndpoint) {
   extensions::StreamFilterParent::Attach(this, std::move(aEndpoint));
   return IPC_OK();
 }
 
 //-----------------------------------------------------------------------------
 // DocumentChannelChild::nsITraceableChannel
@@ -469,16 +538,74 @@ DocumentChannelChild::SetNewListener(nsI
 
   nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);
 
   wrapper.forget(_retval);
   mListener = aListener;
   return NS_OK;
 }
 
+//-----------------------------------------------------------------------------
+// DocumentChannelChild::nsIClassifiedChannel
+
+NS_IMETHODIMP
+DocumentChannelChild::GetMatchedList(nsACString& aList) {
+  aList = mMatchedList;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::GetMatchedProvider(nsACString& aProvider) {
+  aProvider = mMatchedProvider;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::GetMatchedFullHash(nsACString& aFullHash) {
+  aFullHash = mMatchedFullHash;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::SetMatchedInfo(const nsACString& aList,
+                                     const nsACString& aProvider,
+                                     const nsACString& aFullHash) {
+  NS_ENSURE_ARG(!aList.IsEmpty());
+
+  mMatchedList = aList;
+  mMatchedProvider = aProvider;
+  mMatchedFullHash = aFullHash;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::GetMatchedTrackingLists(nsTArray<nsCString>& aLists) {
+  aLists = mMatchedTrackingLists;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::GetMatchedTrackingFullHashes(
+    nsTArray<nsCString>& aFullHashes) {
+  aFullHashes = mMatchedTrackingFullHashes;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::SetMatchedTrackingInfo(
+    const nsTArray<nsCString>& aLists, const nsTArray<nsCString>& aFullHashes) {
+  NS_ENSURE_ARG(!aLists.IsEmpty());
+  // aFullHashes can be empty for non hash-matching algorithm, for example,
+  // host based test entries in preference.
+
+  mMatchedTrackingLists = aLists;
+  mMatchedTrackingFullHashes = aFullHashes;
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 DocumentChannelChild::Cancel(nsresult aStatusCode) {
   if (mCanceled) {
     return NS_OK;
   }
 
   mCanceled = true;
   if (CanSend()) {
@@ -510,10 +637,70 @@ DocumentChannelChild::Resume() {
   if (!--mSuspendCount) {
     SendResume();
   }
 
   mEventQueue->Resume();
   return NS_OK;
 }
 
+NS_IMETHODIMP
+DocumentChannelChild::IsTrackingResource(bool* aIsTrackingResource) {
+  MOZ_ASSERT(!mFirstPartyClassificationFlags ||
+             !mThirdPartyClassificationFlags);
+  *aIsTrackingResource = UrlClassifierCommon::IsTrackingClassificationFlag(
+                             mThirdPartyClassificationFlags) ||
+                         UrlClassifierCommon::IsTrackingClassificationFlag(
+                             mFirstPartyClassificationFlags);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::IsThirdPartyTrackingResource(bool* aIsTrackingResource) {
+  MOZ_ASSERT(
+      !(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags));
+  *aIsTrackingResource = UrlClassifierCommon::IsTrackingClassificationFlag(
+      mThirdPartyClassificationFlags);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::IsSocialTrackingResource(
+    bool* aIsSocialTrackingResource) {
+  MOZ_ASSERT(!mFirstPartyClassificationFlags ||
+             !mThirdPartyClassificationFlags);
+  *aIsSocialTrackingResource =
+      UrlClassifierCommon::IsSocialTrackingClassificationFlag(
+          mThirdPartyClassificationFlags) ||
+      UrlClassifierCommon::IsSocialTrackingClassificationFlag(
+          mFirstPartyClassificationFlags);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::GetClassificationFlags(uint32_t* aClassificationFlags) {
+  MOZ_ASSERT(aClassificationFlags);
+  if (mThirdPartyClassificationFlags) {
+    *aClassificationFlags = mThirdPartyClassificationFlags;
+  } else {
+    *aClassificationFlags = mFirstPartyClassificationFlags;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::GetFirstPartyClassificationFlags(
+    uint32_t* aClassificationFlags) {
+  MOZ_ASSERT(aClassificationFlags);
+  *aClassificationFlags = mFirstPartyClassificationFlags;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelChild::GetThirdPartyClassificationFlags(
+    uint32_t* aClassificationFlags) {
+  MOZ_ASSERT(aClassificationFlags);
+  *aClassificationFlags = mThirdPartyClassificationFlags;
+  return NS_OK;
+}
+
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/ipc/DocumentChannelChild.h
+++ b/netwerk/ipc/DocumentChannelChild.h
@@ -7,40 +7,43 @@
 
 #ifndef mozilla_net_DocumentChannelChild_h
 #define mozilla_net_DocumentChannelChild_h
 
 #include "mozilla/net/ChannelEventQueue.h"
 #include "mozilla/net/PDocumentChannelChild.h"
 #include "nsBaseChannel.h"
 #include "nsIChildChannel.h"
+#include "nsIClassifiedChannel.h"
 #include "nsITraceableChannel.h"
 
 #define DOCUMENT_CHANNEL_CHILD_IID                   \
   {                                                  \
     0x6977bc44, 0xb1db, 0x41b7, {                    \
       0xb5, 0xc5, 0xe2, 0x13, 0x68, 0x22, 0xc9, 0x8f \
     }                                                \
   }
 
 namespace mozilla {
 namespace net {
 
 class DocumentChannelChild final : public PDocumentChannelChild,
                                    public nsBaseChannel,
+                                   public nsIClassifiedChannel,
                                    public nsITraceableChannel {
  public:
   DocumentChannelChild(nsDocShellLoadState* aLoadState,
                        class LoadInfo* aLoadInfo,
                        const nsString* aInitiatorType, nsLoadFlags aLoadFlags,
                        uint32_t aLoadType, uint32_t aCacheKey, bool aIsActive,
                        bool aIsTopLevelDoc, bool aHasNonEmptySandboxingFlags);
 
   NS_DECL_ISUPPORTS_INHERITED;
   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
+  NS_DECL_NSICLASSIFIEDCHANNEL
   NS_DECL_NSITRACEABLECHANNEL
 
   NS_DECLARE_STATIC_IID_ACCESSOR(DOCUMENT_CHANNEL_CHILD_IID)
 
   // nsIRequest
   NS_IMETHOD Cancel(nsresult status) override;
   NS_IMETHOD Suspend() override;
   NS_IMETHOD Resume() override;
@@ -67,34 +70,60 @@ class DocumentChannelChild final : publi
       const uint32_t& aRedirectMode, const uint32_t& aRedirectFlags,
       const Maybe<uint32_t>& aContentDisposition,
       const Maybe<nsString>& aContentDispositionFilename,
       RedirectToRealChannelResolver&& aResolve);
 
   mozilla::ipc::IPCResult RecvAttachStreamFilter(
       Endpoint<extensions::PStreamFilterParent>&& aEndpoint);
 
+  mozilla::ipc::IPCResult RecvNotifyClassificationFlags(
+      const uint32_t& aClassificationFlags, const bool& aIsThirdParty);
+  mozilla::ipc::IPCResult RecvNotifyChannelClassifierProtectionDisabled(
+      const uint32_t& aAcceptedReason);
+  mozilla::ipc::IPCResult RecvNotifyCookieAllowed();
+  mozilla::ipc::IPCResult RecvNotifyCookieBlocked(
+      const uint32_t& aRejectedReason);
+
+  mozilla::ipc::IPCResult RecvSetClassifierMatchedInfo(
+      const nsCString& aList, const nsCString& aProvider,
+      const nsCString& aFullHash);
+  mozilla::ipc::IPCResult RecvSetClassifierMatchedTrackingInfo(
+      const nsCString& aLists, const nsCString& aFullHash);
+
   mozilla::ipc::IPCResult RecvConfirmRedirect(
       const LoadInfoArgs& aLoadInfo, nsIURI* aNewUri,
       ConfirmRedirectResolver&& aResolve);
 
+  void DoFailedAsyncOpen(const nsresult& aStatusCode);
+
   const nsTArray<DocumentChannelRedirect>& GetRedirectChain() const {
     return mRedirects;
   }
 
+  friend class NeckoTargetChannelEvent<DocumentChannelChild>;
+
  private:
-  friend class NeckoTargetChannelFunctionEvent;
   void ShutdownListeners(nsresult aStatusCode);
 
   ~DocumentChannelChild() = default;
 
   RefPtr<ChannelEventQueue> mEventQueue;
   nsCOMPtr<nsIChannel> mRedirectChannel;
   nsTArray<DocumentChannelRedirect> mRedirects;
 
+  // Classified channel's matched information
+  uint32_t mFirstPartyClassificationFlags = 0;
+  uint32_t mThirdPartyClassificationFlags = 0;
+  nsCString mMatchedList;
+  nsCString mMatchedProvider;
+  nsCString mMatchedFullHash;
+  nsTArray<nsCString> mMatchedTrackingLists;
+  nsTArray<nsCString> mMatchedTrackingFullHashes;
+
   RedirectToRealChannelResolver mRedirectResolver;
 
   TimeStamp mAsyncOpenTime;
   const RefPtr<nsDocShellLoadState> mLoadState;
   const Maybe<nsString> mInitiatorType;
   const uint32_t mLoadType;
   const uint32_t mCacheKey;
   const bool mIsActive;
--- a/netwerk/ipc/DocumentChannelParent.cpp
+++ b/netwerk/ipc/DocumentChannelParent.cpp
@@ -284,27 +284,16 @@ void DocumentChannelParent::FinishReplac
         },
         [redirectChannel](const ClassifierMatchedTrackingInfoParams& aParams) {
           redirectChannel->SetClassifierMatchedTrackingInfo(
               aParams.mLists, aParams.mFullHashes);
         },
         [redirectChannel](const ClassificationFlagsParams& aParams) {
           redirectChannel->NotifyClassificationFlags(
               aParams.mClassificationFlags, aParams.mIsThirdParty);
-        },
-        [redirectChannel](
-            const NotifyChannelClassifierProtectionDisabledParams& aParams) {
-          redirectChannel->NotifyChannelClassifierProtectionDisabled(
-              aParams.mAcceptedReason);
-        },
-        [redirectChannel](const NotifyCookieAllowedParams&) {
-          redirectChannel->NotifyCookieAllowed();
-        },
-        [redirectChannel](const NotifyCookieBlockedParams& aParams) {
-          redirectChannel->NotifyCookieBlocked(aParams.mRejectedReason);
         });
   }
 
   RefPtr<HttpChannelParent> httpParent = do_QueryObject(redirectChannel);
   if (httpParent) {
     RefPtr<HttpChannelSecurityWarningReporter> reporter = httpParent;
     for (auto& variant : mSecurityWarningFunctions) {
       variant.match(
@@ -698,82 +687,99 @@ DocumentChannelParent::GetInterface(cons
 
   return QueryInterface(aIID, result);
 }
 
 // Rather than forwarding all these nsIParentChannel functions to the child, we
 // cache a list of them, and then ask the 'real' channel to forward them for us
 // after it's created.
 NS_IMETHODIMP
+DocumentChannelParent::NotifyChannelClassifierProtectionDisabled(
+    uint32_t aAcceptedReason) {
+  if (CanSend()) {
+    Unused << SendNotifyChannelClassifierProtectionDisabled(aAcceptedReason);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelParent::NotifyCookieAllowed() {
+  if (CanSend()) {
+    Unused << SendNotifyCookieAllowed();
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
+  if (CanSend()) {
+    Unused << SendNotifyCookieBlocked(aRejectedReason);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 DocumentChannelParent::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   mIParentChannelFunctions.AppendElement(
       IParentChannelFunction{VariantIndex<0>{}, aState});
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DocumentChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
                                                 const nsACString& aProvider,
                                                 const nsACString& aFullHash) {
   ClassifierMatchedInfoParams params;
   params.mList = aList;
   params.mProvider = aProvider;
   params.mFullHash = aFullHash;
 
+  if (CanSend()) {
+    Unused << SendSetClassifierMatchedInfo(params.mList, params.mProvider,
+                                           params.mFullHash);
+  }
+
   mIParentChannelFunctions.AppendElement(
       IParentChannelFunction{VariantIndex<1>{}, std::move(params)});
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DocumentChannelParent::SetClassifierMatchedTrackingInfo(
     const nsACString& aLists, const nsACString& aFullHash) {
   ClassifierMatchedTrackingInfoParams params;
   params.mLists = aLists;
   params.mFullHashes = aFullHash;
 
+  if (CanSend()) {
+    Unused << SendSetClassifierMatchedTrackingInfo(params.mLists,
+                                                   params.mFullHashes);
+  }
+
   mIParentChannelFunctions.AppendElement(
       IParentChannelFunction{VariantIndex<2>{}, std::move(params)});
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DocumentChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
                                                  bool aIsThirdParty) {
+  if (CanSend()) {
+    Unused << SendNotifyClassificationFlags(aClassificationFlags,
+                                            aIsThirdParty);
+  }
+
   mIParentChannelFunctions.AppendElement(IParentChannelFunction{
       VariantIndex<3>{},
       ClassificationFlagsParams{aClassificationFlags, aIsThirdParty}});
   return NS_OK;
 }
 
 NS_IMETHODIMP
-DocumentChannelParent::NotifyChannelClassifierProtectionDisabled(
-    uint32_t aAcceptedReason) {
-  mIParentChannelFunctions.AppendElement(IParentChannelFunction{
-      VariantIndex<4>{},
-      NotifyChannelClassifierProtectionDisabledParams{aAcceptedReason}});
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DocumentChannelParent::NotifyCookieAllowed() {
-  mIParentChannelFunctions.AppendElement(
-      IParentChannelFunction{VariantIndex<5>{}, NotifyCookieAllowedParams()});
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-DocumentChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
-  mIParentChannelFunctions.AppendElement(IParentChannelFunction{
-      VariantIndex<6>{}, NotifyCookieBlockedParams{aRejectedReason}});
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 DocumentChannelParent::Delete() {
   // TODO - not sure we need it, but should delete the child or call on the
   // child to release the parent.
   if (!CanSend()) {
     return NS_ERROR_UNEXPECTED;
   }
   Unused << SendDeleteSelf();
   return NS_OK;
--- a/netwerk/ipc/DocumentChannelParent.h
+++ b/netwerk/ipc/DocumentChannelParent.h
@@ -125,32 +125,19 @@ class DocumentChannelParent : public nsI
   struct ClassifierMatchedTrackingInfoParams {
     nsCString mLists;
     nsCString mFullHashes;
   };
   struct ClassificationFlagsParams {
     uint32_t mClassificationFlags;
     bool mIsThirdParty;
   };
-
-  struct NotifyChannelClassifierProtectionDisabledParams {
-    uint32_t mAcceptedReason;
-  };
-
-  struct NotifyCookieAllowedParams {};
-
-  struct NotifyCookieBlockedParams {
-    uint32_t mRejectedReason;
-  };
-
   typedef mozilla::Variant<
       nsIHttpChannel::FlashPluginState, ClassifierMatchedInfoParams,
-      ClassifierMatchedTrackingInfoParams, ClassificationFlagsParams,
-      NotifyChannelClassifierProtectionDisabledParams,
-      NotifyCookieAllowedParams, NotifyCookieBlockedParams>
+      ClassifierMatchedTrackingInfoParams, ClassificationFlagsParams>
       IParentChannelFunction;
 
   // Store a list of all the attribute setters that have been called on this
   // channel, so that we can repeat them on the real channel that we redirect
   // to.
   nsTArray<IParentChannelFunction> mIParentChannelFunctions;
 
   // This defines a variant this describes all the functions
--- a/netwerk/ipc/PDocumentChannel.ipdl
+++ b/netwerk/ipc/PDocumentChannel.ipdl
@@ -45,16 +45,25 @@ parent:
   async __delete__();
 
 child:
 
   // Used to cancel child channel if we hit errors during creating and
   // AsyncOpen of nsHttpChannel on the parent.
   async FailedAsyncOpen(nsresult status);
 
+  async NotifyClassificationFlags(uint32_t classificationFlags, bool
+isThirdParty);
+  async NotifyChannelClassifierProtectionDisabled(uint32_t acceptedReason);
+  async NotifyCookieAllowed();
+  async NotifyCookieBlocked(uint32_t rejectedReason);
+
+  async SetClassifierMatchedInfo(nsCString list, nsCString provider, nsCString fullHash);
+  async SetClassifierMatchedTrackingInfo(nsCString lists, nsCString fullHash);
+  
   async AttachStreamFilter(Endpoint<PStreamFilterParent> aEndpoint);
 
   // This message is sent to a child that has been redirected to another process.
   // As a consequence, it should cleanup the channel listeners and remove the
   // request from the loadGroup.
   // aStatus must be an error result.
   async DisconnectChildListeners(nsresult aStatus);
 
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -28,32 +28,32 @@ using mozilla::dom::ContentChild;
 using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
 
 namespace mozilla {
 namespace net {
 
-FTPChannelChild::FTPChannelChild(nsIURI* aUri)
+FTPChannelChild::FTPChannelChild(nsIURI* uri)
     : mIPCOpen(false),
-      mEventQ(new ChannelEventQueue(static_cast<nsIFTPChannel*>(this))),
       mUnknownDecoderInvolved(false),
       mCanceled(false),
       mSuspendCount(0),
       mIsPending(false),
       mLastModifiedTime(0),
       mStartPos(0),
       mDivertingToParent(false),
       mFlushedForDiversion(false),
       mSuspendSent(false) {
   LOG(("Creating FTPChannelChild @%p\n", this));
   // grab a reference to the handler to ensure that it doesn't go away.
   NS_ADDREF(gFtpHandler);
-  SetURI(aUri);
+  SetURI(uri);
+  mEventQ = new ChannelEventQueue(static_cast<nsIFTPChannel*>(this));
 
   // We could support thread retargeting, but as long as we're being driven by
   // IPDL on the main thread it doesn't buy us anything.
   DisallowThreadRetargeting();
 }
 
 FTPChannelChild::~FTPChannelChild() {
   LOG(("Destroying FTPChannelChild @%p\n", this));
@@ -79,58 +79,58 @@ void FTPChannelChild::ReleaseIPDLReferen
 NS_IMPL_ISUPPORTS_INHERITED(FTPChannelChild, nsBaseChannel, nsIFTPChannel,
                             nsIUploadChannel, nsIResumableChannel,
                             nsIProxiedChannel, nsIChildChannel,
                             nsIDivertableChannel)
 
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-FTPChannelChild::GetLastModifiedTime(PRTime* aLastModifiedTime) {
-  *aLastModifiedTime = mLastModifiedTime;
+FTPChannelChild::GetLastModifiedTime(PRTime* lastModifiedTime) {
+  *lastModifiedTime = mLastModifiedTime;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FTPChannelChild::SetLastModifiedTime(PRTime aLastModifiedTime) {
+FTPChannelChild::SetLastModifiedTime(PRTime lastModifiedTime) {
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID) {
   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
   mStartPos = aStartPos;
   mEntityID = aEntityID;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FTPChannelChild::GetEntityID(nsACString& aEntityID) {
-  aEntityID = mEntityID;
+FTPChannelChild::GetEntityID(nsACString& entityID) {
+  entityID = mEntityID;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::GetProxyInfo(nsIProxyInfo** aProxyInfo) { DROP_DEAD(); }
 
 NS_IMETHODIMP
-FTPChannelChild::SetUploadStream(nsIInputStream* aStream,
-                                 const nsACString& aContentType,
-                                 int64_t aContentLength) {
+FTPChannelChild::SetUploadStream(nsIInputStream* stream,
+                                 const nsACString& contentType,
+                                 int64_t contentLength) {
   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
-  mUploadStream = aStream;
+  mUploadStream = stream;
   // NOTE: contentLength is intentionally ignored here.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FTPChannelChild::GetUploadStream(nsIInputStream** aStream) {
-  NS_ENSURE_ARG_POINTER(aStream);
-  *aStream = mUploadStream;
-  NS_IF_ADDREF(*aStream);
+FTPChannelChild::GetUploadStream(nsIInputStream** stream) {
+  NS_ENSURE_ARG_POINTER(stream);
+  *stream = mUploadStream;
+  NS_IF_ADDREF(*stream);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::AsyncOpen(nsIStreamListener* aListener) {
   nsCOMPtr<nsIStreamListener> listener = aListener;
   nsresult rv =
       nsContentSecurityManager::doContentSecurityCheck(this, listener);
@@ -202,52 +202,78 @@ FTPChannelChild::AsyncOpen(nsIStreamList
 
   mIsPending = true;
   mWasOpened = true;
 
   return rv;
 }
 
 NS_IMETHODIMP
-FTPChannelChild::IsPending(bool* aResult) {
-  *aResult = mIsPending;
+FTPChannelChild::IsPending(bool* result) {
+  *result = mIsPending;
   return NS_OK;
 }
 
-nsresult FTPChannelChild::OpenContentStream(bool aAsync,
-                                            nsIInputStream** aStream,
-                                            nsIChannel** aChannel) {
+nsresult FTPChannelChild::OpenContentStream(bool async, nsIInputStream** stream,
+                                            nsIChannel** channel) {
   MOZ_CRASH("FTPChannel*Child* should never have OpenContentStream called!");
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelChild::PFTPChannelChild
 //-----------------------------------------------------------------------------
 
+class FTPStartRequestEvent : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  FTPStartRequestEvent(FTPChannelChild* aChild, const nsresult& aChannelStatus,
+                       const int64_t& aContentLength,
+                       const nsCString& aContentType,
+                       const PRTime& aLastModified, const nsCString& aEntityID,
+                       const URIParams& aURI)
+      : NeckoTargetChannelEvent<FTPChannelChild>(aChild),
+        mChannelStatus(aChannelStatus),
+        mContentLength(aContentLength),
+        mContentType(aContentType),
+        mLastModified(aLastModified),
+        mEntityID(aEntityID),
+        mURI(aURI) {}
+
+  void Run() override {
+    mChild->DoOnStartRequest(mChannelStatus, mContentLength, mContentType,
+                             mLastModified, mEntityID, mURI);
+  }
+
+ private:
+  nsresult mChannelStatus;
+  int64_t mContentLength;
+  nsCString mContentType;
+  PRTime mLastModified;
+  nsCString mEntityID;
+  URIParams mURI;
+};
+
 mozilla::ipc::IPCResult FTPChannelChild::RecvOnStartRequest(
     const nsresult& aChannelStatus, const int64_t& aContentLength,
     const nsCString& aContentType, const PRTime& aLastModified,
     const nsCString& aEntityID, const URIParams& aURI) {
   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
   // stage, as they are set in the listener's OnStartRequest.
   MOZ_RELEASE_ASSERT(
       !mFlushedForDiversion,
       "mFlushedForDiversion should be unset before OnStartRequest!");
   MOZ_RELEASE_ASSERT(
       !mDivertingToParent,
       "mDivertingToParent should be unset before OnStartRequest!");
 
   LOG(("FTPChannelChild::RecvOnStartRequest [this=%p]\n", this));
 
-  RefPtr<FTPChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=]() {
-    self->DoOnStartRequest(aChannelStatus, aContentLength, aContentType,
-                           aLastModified, aEntityID, aURI);
-  }));
+  mEventQ->RunOrEnqueue(
+      new FTPStartRequestEvent(this, aChannelStatus, aContentLength,
+                               aContentType, aLastModified, aEntityID, aURI));
   return IPC_OK();
 }
 
 void FTPChannelChild::DoOnStartRequest(const nsresult& aChannelStatus,
                                        const int64_t& aContentLength,
                                        const nsCString& aContentType,
                                        const PRTime& aLastModified,
                                        const nsCString& aEntityID,
@@ -297,107 +323,178 @@ void FTPChannelChild::DoOnStartRequest(c
   if (mDivertingToParent) {
     mListener = nullptr;
     if (mLoadGroup) {
       mLoadGroup->RemoveRequest(this, nullptr, mStatus);
     }
   }
 }
 
+class FTPDataAvailableEvent : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  FTPDataAvailableEvent(FTPChannelChild* aChild, const nsresult& aChannelStatus,
+                        const nsCString& aData, const uint64_t& aOffset,
+                        const uint32_t& aCount)
+      : NeckoTargetChannelEvent<FTPChannelChild>(aChild),
+        mChannelStatus(aChannelStatus),
+        mData(aData),
+        mOffset(aOffset),
+        mCount(aCount) {}
+
+  void Run() override {
+    mChild->DoOnDataAvailable(mChannelStatus, mData, mOffset, mCount);
+  }
+
+ private:
+  nsresult mChannelStatus;
+  nsCString mData;
+  uint64_t mOffset;
+  uint32_t mCount;
+};
+
 mozilla::ipc::IPCResult FTPChannelChild::RecvOnDataAvailable(
-    const nsresult& aChannelStatus, const nsCString& aData,
-    const uint64_t& aOffset, const uint32_t& aCount) {
+    const nsresult& channelStatus, const nsCString& data,
+    const uint64_t& offset, const uint32_t& count) {
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
                      "Should not be receiving any more callbacks from parent!");
 
   LOG(("FTPChannelChild::RecvOnDataAvailable [this=%p]\n", this));
 
-  RefPtr<FTPChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-                            this,
-                            [=]() {
-                              self->DoOnDataAvailable(aChannelStatus, aData,
-                                                      aOffset, aCount);
-                            }),
-                        mDivertingToParent);
+  mEventQ->RunOrEnqueue(
+      new FTPDataAvailableEvent(this, channelStatus, data, offset, count),
+      mDivertingToParent);
 
   return IPC_OK();
 }
 
-void FTPChannelChild::DoOnDataAvailable(const nsresult& aChannelStatus,
-                                        const nsCString& aData,
-                                        const uint64_t& aOffset,
-                                        const uint32_t& aCount) {
+class MaybeDivertOnDataFTPEvent
+    : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  MaybeDivertOnDataFTPEvent(FTPChannelChild* child, const nsCString& data,
+                            const uint64_t& offset, const uint32_t& count)
+      : NeckoTargetChannelEvent<FTPChannelChild>(child),
+        mData(data),
+        mOffset(offset),
+        mCount(count) {}
+
+  void Run() override { mChild->MaybeDivertOnData(mData, mOffset, mCount); }
+
+ private:
+  nsCString mData;
+  uint64_t mOffset;
+  uint32_t mCount;
+};
+
+void FTPChannelChild::MaybeDivertOnData(const nsCString& data,
+                                        const uint64_t& offset,
+                                        const uint32_t& count) {
+  if (mDivertingToParent) {
+    SendDivertOnDataAvailable(data, offset, count);
+  }
+}
+
+void FTPChannelChild::DoOnDataAvailable(const nsresult& channelStatus,
+                                        const nsCString& data,
+                                        const uint64_t& offset,
+                                        const uint32_t& count) {
   LOG(("FTPChannelChild::DoOnDataAvailable [this=%p]\n", this));
 
   if (!mCanceled && NS_SUCCEEDED(mStatus)) {
-    mStatus = aChannelStatus;
+    mStatus = channelStatus;
   }
 
   if (mDivertingToParent) {
     MOZ_RELEASE_ASSERT(
         !mFlushedForDiversion,
         "Should not be processing any more callbacks from parent!");
 
-    SendDivertOnDataAvailable(aData, aOffset, aCount);
-    return;
-  }
-
-  if (mCanceled) {
+    SendDivertOnDataAvailable(data, offset, count);
     return;
   }
 
+  if (mCanceled) return;
+
   if (mUnknownDecoderInvolved) {
-    RefPtr<FTPChannelChild> self = this;
     mUnknownDecoderEventQ.AppendElement(
-        MakeUnique<NeckoTargetChannelFunctionEvent>(this, [=]() {
-          if (self->mDivertingToParent) {
-            self->SendDivertOnDataAvailable(aData, aOffset, aCount);
-          }
-        }));
+        MakeUnique<MaybeDivertOnDataFTPEvent>(this, data, offset, count));
   }
 
   // NOTE: the OnDataAvailable contract requires the client to read all the data
   // in the inputstream.  This code relies on that ('data' will go away after
   // this function).  Apparently the previous, non-e10s behavior was to actually
   // support only reading part of the data, allowing later calls to read the
   // rest.
   nsCOMPtr<nsIInputStream> stringStream;
   nsresult rv =
       NS_NewByteInputStream(getter_AddRefs(stringStream),
-                            MakeSpan(aData).To(aCount), NS_ASSIGNMENT_DEPEND);
+                            MakeSpan(data).To(count), NS_ASSIGNMENT_DEPEND);
   if (NS_FAILED(rv)) {
     Cancel(rv);
     return;
   }
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
-  rv = mListener->OnDataAvailable(this, stringStream, aOffset, aCount);
-  if (NS_FAILED(rv)) {
-    Cancel(rv);
-  }
+  rv = mListener->OnDataAvailable(this, stringStream, offset, count);
+  if (NS_FAILED(rv)) Cancel(rv);
   stringStream->Close();
 }
 
+class FTPStopRequestEvent : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  FTPStopRequestEvent(FTPChannelChild* aChild, const nsresult& aChannelStatus,
+                      const nsCString& aErrorMsg, bool aUseUTF8)
+      : NeckoTargetChannelEvent<FTPChannelChild>(aChild),
+        mChannelStatus(aChannelStatus),
+        mErrorMsg(aErrorMsg),
+        mUseUTF8(aUseUTF8) {}
+
+  void Run() override {
+    mChild->DoOnStopRequest(mChannelStatus, mErrorMsg, mUseUTF8);
+  }
+
+ private:
+  nsresult mChannelStatus;
+  nsCString mErrorMsg;
+  bool mUseUTF8;
+};
+
 mozilla::ipc::IPCResult FTPChannelChild::RecvOnStopRequest(
     const nsresult& aChannelStatus, const nsCString& aErrorMsg,
     const bool& aUseUTF8) {
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
                      "Should not be receiving any more callbacks from parent!");
 
   LOG(("FTPChannelChild::RecvOnStopRequest [this=%p status=%" PRIx32 "]\n",
        this, static_cast<uint32_t>(aChannelStatus)));
 
-  RefPtr<FTPChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=]() {
-    self->DoOnStopRequest(aChannelStatus, aErrorMsg, aUseUTF8);
-  }));
+  mEventQ->RunOrEnqueue(
+      new FTPStopRequestEvent(this, aChannelStatus, aErrorMsg, aUseUTF8));
   return IPC_OK();
 }
 
+class MaybeDivertOnStopFTPEvent
+    : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  MaybeDivertOnStopFTPEvent(FTPChannelChild* child,
+                            const nsresult& aChannelStatus)
+      : NeckoTargetChannelEvent<FTPChannelChild>(child),
+        mChannelStatus(aChannelStatus) {}
+
+  void Run() override { mChild->MaybeDivertOnStop(mChannelStatus); }
+
+ private:
+  nsresult mChannelStatus;
+};
+
+void FTPChannelChild::MaybeDivertOnStop(const nsresult& aChannelStatus) {
+  if (mDivertingToParent) {
+    SendDivertOnStopRequest(aChannelStatus);
+  }
+}
+
 void FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus,
                                       const nsCString& aErrorMsg,
                                       bool aUseUTF8) {
   LOG(("FTPChannelChild::DoOnStopRequest [this=%p status=%" PRIx32 "]\n", this,
        static_cast<uint32_t>(aChannelStatus)));
 
   if (mDivertingToParent) {
     MOZ_RELEASE_ASSERT(
@@ -406,84 +503,92 @@ void FTPChannelChild::DoOnStopRequest(co
 
     SendDivertOnStopRequest(aChannelStatus);
     return;
   }
 
   if (!mCanceled) mStatus = aChannelStatus;
 
   if (mUnknownDecoderInvolved) {
-    RefPtr<FTPChannelChild> self = this;
     mUnknownDecoderEventQ.AppendElement(
-        MakeUnique<NeckoTargetChannelFunctionEvent>(this, [=]() {
-          if (self->mDivertingToParent) {
-            self->SendDivertOnStopRequest(aChannelStatus);
-          }
-        }));
+        MakeUnique<MaybeDivertOnStopFTPEvent>(this, aChannelStatus));
   }
 
   {  // Ensure that all queued ipdl events are dispatched before
     // we initiate protocol deletion below.
     mIsPending = false;
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
     (void)mListener->OnStopRequest(this, aChannelStatus);
 
     mListener = nullptr;
 
-    if (mLoadGroup) {
-      mLoadGroup->RemoveRequest(this, nullptr, aChannelStatus);
-    }
+    if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, aChannelStatus);
   }
 
   // This calls NeckoChild::DeallocPFTPChannelChild(), which deletes |this| if
   // IPDL holds the last reference.  Don't rely on |this| existing after here!
   Send__delete__(this);
 }
 
+class FTPFailedAsyncOpenEvent
+    : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  FTPFailedAsyncOpenEvent(FTPChannelChild* aChild, nsresult aStatus)
+      : NeckoTargetChannelEvent<FTPChannelChild>(aChild), mStatus(aStatus) {}
+
+  void Run() override { mChild->DoFailedAsyncOpen(mStatus); }
+
+ private:
+  nsresult mStatus;
+};
+
 mozilla::ipc::IPCResult FTPChannelChild::RecvFailedAsyncOpen(
-    const nsresult& aStatusCode) {
+    const nsresult& statusCode) {
   LOG(("FTPChannelChild::RecvFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
-       this, static_cast<uint32_t>(aStatusCode)));
-  RefPtr<FTPChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=]() { self->DoFailedAsyncOpen(aStatusCode); }));
+       this, static_cast<uint32_t>(statusCode)));
+  mEventQ->RunOrEnqueue(new FTPFailedAsyncOpenEvent(this, statusCode));
   return IPC_OK();
 }
 
-void FTPChannelChild::DoFailedAsyncOpen(const nsresult& aStatusCode) {
+void FTPChannelChild::DoFailedAsyncOpen(const nsresult& statusCode) {
   LOG(("FTPChannelChild::DoFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
-       this, static_cast<uint32_t>(aStatusCode)));
-  mStatus = aStatusCode;
+       this, static_cast<uint32_t>(statusCode)));
+  mStatus = statusCode;
 
-  if (mLoadGroup) {
-    mLoadGroup->RemoveRequest(this, nullptr, aStatusCode);
-  }
+  if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, statusCode);
 
   if (mListener) {
     mListener->OnStartRequest(this);
     mIsPending = false;
-    mListener->OnStopRequest(this, aStatusCode);
+    mListener->OnStopRequest(this, statusCode);
   } else {
     mIsPending = false;
   }
 
   mListener = nullptr;
 
-  if (mIPCOpen) {
-    Send__delete__(this);
+  if (mIPCOpen) Send__delete__(this);
+}
+
+class FTPFlushedForDiversionEvent
+    : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  explicit FTPFlushedForDiversionEvent(FTPChannelChild* aChild)
+      : NeckoTargetChannelEvent<FTPChannelChild>(aChild) {
+    MOZ_RELEASE_ASSERT(aChild);
   }
-}
+
+  void Run() override { mChild->FlushedForDiversion(); }
+};
 
 mozilla::ipc::IPCResult FTPChannelChild::RecvFlushedForDiversion() {
   LOG(("FTPChannelChild::RecvFlushedForDiversion [this=%p]\n", this));
   MOZ_ASSERT(mDivertingToParent);
 
-  RefPtr<FTPChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=]() { self->FlushedForDiversion(); }));
+  mEventQ->RunOrEnqueue(new FTPFlushedForDiversionEvent(this), true);
   return IPC_OK();
 }
 
 void FTPChannelChild::FlushedForDiversion() {
   LOG(("FTPChannelChild::FlushedForDiversion [this=%p]\n", this));
   MOZ_RELEASE_ASSERT(mDivertingToParent);
 
   // Once this is set, it should not be unset before FTPChannelChild is taken
@@ -502,41 +607,40 @@ mozilla::ipc::IPCResult FTPChannelChild:
   // DivertTo() has been called on parent, so we can now start sending queued
   // IPDL messages back to parent listener.
   if (NS_WARN_IF(NS_FAILED(Resume()))) {
     return IPC_FAIL_NO_REASON(this);
   }
   return IPC_OK();
 }
 
+class FTPDeleteSelfEvent : public NeckoTargetChannelEvent<FTPChannelChild> {
+ public:
+  explicit FTPDeleteSelfEvent(FTPChannelChild* aChild)
+      : NeckoTargetChannelEvent<FTPChannelChild>(aChild) {}
+  void Run() override { mChild->DoDeleteSelf(); }
+};
+
 mozilla::ipc::IPCResult FTPChannelChild::RecvDeleteSelf() {
-  RefPtr<FTPChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=]() { self->DoDeleteSelf(); }));
+  mEventQ->RunOrEnqueue(new FTPDeleteSelfEvent(this));
   return IPC_OK();
 }
 
 void FTPChannelChild::DoDeleteSelf() {
-  if (mIPCOpen) {
-    Send__delete__(this);
-  }
+  if (mIPCOpen) Send__delete__(this);
 }
 
 NS_IMETHODIMP
-FTPChannelChild::Cancel(nsresult aStatus) {
+FTPChannelChild::Cancel(nsresult status) {
   LOG(("FTPChannelChild::Cancel [this=%p]\n", this));
-  if (mCanceled) {
-    return NS_OK;
-  }
+  if (mCanceled) return NS_OK;
 
   mCanceled = true;
-  mStatus = aStatus;
-  if (mIPCOpen) {
-    SendCancel(aStatus);
-  }
+  mStatus = status;
+  if (mIPCOpen) SendCancel(status);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::Suspend() {
   NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
 
   LOG(("FTPChannelChild::Suspend [this=%p]\n", this));
@@ -571,17 +675,17 @@ FTPChannelChild::Resume() {
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelChild::nsIChildChannel
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-FTPChannelChild::ConnectParent(uint32_t aId) {
+FTPChannelChild::ConnectParent(uint32_t id) {
   NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
   NS_ENSURE_TRUE(
       !static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
       NS_ERROR_FAILURE);
 
   LOG(("FTPChannelChild::ConnectParent [this=%p]\n", this));
 
   mozilla::dom::BrowserChild* browserChild = nullptr;
@@ -597,42 +701,40 @@ FTPChannelChild::ConnectParent(uint32_t 
 
   // This must happen before the constructor message is sent.
   SetupNeckoTarget();
 
   // The socket transport in the chrome process now holds a logical ref to us
   // until OnStopRequest, or we do a redirect, or we hit an IPDL error.
   AddIPDLReference();
 
-  FTPChannelConnectArgs connectArgs(aId);
+  FTPChannelConnectArgs connectArgs(id);
 
   if (!gNeckoChild->SendPFTPChannelConstructor(
           this, browserChild, IPC::SerializedLoadContext(this), connectArgs)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-FTPChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener,
+FTPChannelChild::CompleteRedirectSetup(nsIStreamListener* listener,
                                        nsISupports* aContext) {
   LOG(("FTPChannelChild::CompleteRedirectSetup [this=%p]\n", this));
 
   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
 
   mIsPending = true;
   mWasOpened = true;
-  mListener = aListener;
+  mListener = listener;
 
   // add ourselves to the load group.
-  if (mLoadGroup) {
-    mLoadGroup->AddRequest(this, nullptr);
-  }
+  if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr);
 
   // We already have an open IPDL connection to the parent. If on-modify-request
   // listeners or load group observers canceled us, let the parent handle it
   // and send it back to us naturally.
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
--- a/netwerk/protocol/ftp/FTPChannelChild.h
+++ b/netwerk/protocol/ftp/FTPChannelChild.h
@@ -48,81 +48,92 @@ class FTPChannelChild final : public PFT
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIFTPCHANNEL
   NS_DECL_NSIUPLOADCHANNEL
   NS_DECL_NSIRESUMABLECHANNEL
   NS_DECL_NSIPROXIEDCHANNEL
   NS_DECL_NSICHILDCHANNEL
   NS_DECL_NSIDIVERTABLECHANNEL
 
-  NS_IMETHOD Cancel(nsresult aStatus) override;
+  NS_IMETHOD Cancel(nsresult status) override;
   NS_IMETHOD Suspend() override;
   NS_IMETHOD Resume() override;
 
-  explicit FTPChannelChild(nsIURI* aUri);
+  explicit FTPChannelChild(nsIURI* uri);
 
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
-  NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
+  NS_IMETHOD AsyncOpen(nsIStreamListener* listener) override;
 
   // Note that we handle this ourselves, overriding the nsBaseChannel
   // default behavior, in order to be e10s-friendly.
-  NS_IMETHOD IsPending(bool* aResult) override;
+  NS_IMETHOD IsPending(bool* result) override;
 
-  nsresult OpenContentStream(bool aAsync, nsIInputStream** aStream,
-                             nsIChannel** aChannel) override;
+  nsresult OpenContentStream(bool async, nsIInputStream** stream,
+                             nsIChannel** channel) override;
 
-  bool IsSuspended() const;
+  bool IsSuspended();
 
   void FlushedForDiversion();
 
  protected:
   virtual ~FTPChannelChild();
 
   mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& aChannelStatus,
                                              const int64_t& aContentLength,
                                              const nsCString& aContentType,
                                              const PRTime& aLastModified,
                                              const nsCString& aEntityID,
                                              const URIParams& aURI) override;
-  mozilla::ipc::IPCResult RecvOnDataAvailable(const nsresult& aChannelStatus,
-                                              const nsCString& aData,
-                                              const uint64_t& aOffset,
-                                              const uint32_t& aCount) override;
-  mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& aChannelStatus,
+  mozilla::ipc::IPCResult RecvOnDataAvailable(const nsresult& channelStatus,
+                                              const nsCString& data,
+                                              const uint64_t& offset,
+                                              const uint32_t& count) override;
+  mozilla::ipc::IPCResult RecvOnStopRequest(const nsresult& channelStatus,
                                             const nsCString& aErrorMsg,
                                             const bool& aUseUTF8) override;
   mozilla::ipc::IPCResult RecvFailedAsyncOpen(
-      const nsresult& aStatusCode) override;
+      const nsresult& statusCode) override;
   mozilla::ipc::IPCResult RecvFlushedForDiversion() override;
   mozilla::ipc::IPCResult RecvDivertMessages() override;
   mozilla::ipc::IPCResult RecvDeleteSelf() override;
 
   void DoOnStartRequest(const nsresult& aChannelStatus,
                         const int64_t& aContentLength,
                         const nsCString& aContentType,
                         const PRTime& aLastModified, const nsCString& aEntityID,
                         const URIParams& aURI);
-  void DoOnDataAvailable(const nsresult& aChannelStatus, const nsCString& aData,
-                         const uint64_t& aOffset, const uint32_t& aCount);
-  void DoOnStopRequest(const nsresult& StatusCode, const nsCString& aErrorMsg,
+  void DoOnDataAvailable(const nsresult& channelStatus, const nsCString& data,
+                         const uint64_t& offset, const uint32_t& count);
+  void MaybeDivertOnData(const nsCString& data, const uint64_t& offset,
+                         const uint32_t& count);
+  void MaybeDivertOnStop(const nsresult& statusCode);
+  void DoOnStopRequest(const nsresult& statusCode, const nsCString& aErrorMsg,
                        bool aUseUTF8);
-  void DoFailedAsyncOpen(const nsresult& aStatusCode);
+  void DoFailedAsyncOpen(const nsresult& statusCode);
   void DoDeleteSelf();
 
   void SetupNeckoTarget() override;
 
-  friend class NeckoTargetChannelFunctionEvent;
+  friend class FTPStartRequestEvent;
+  friend class FTPDataAvailableEvent;
+  friend class MaybeDivertOnDataFTPEvent;
+  friend class FTPStopRequestEvent;
+  friend class MaybeDivertOnStopFTPEvent;
+  friend class FTPFailedAsyncOpenEvent;
+  friend class FTPFlushedForDiversionEvent;
+  friend class FTPDeleteSelfEvent;
+  friend class NeckoTargetChannelEvent<FTPChannelChild>;
 
  private:
   nsCOMPtr<nsIInputStream> mUploadStream;
 
   bool mIPCOpen;
-  const RefPtr<ChannelEventQueue> mEventQ;
+  RefPtr<ChannelEventQueue> mEventQ;
 
   // If nsUnknownDecoder is involved we queue onDataAvailable (and possibly
   // OnStopRequest) so that we can divert them if needed when the listener's
   // OnStartRequest is finally called
   nsTArray<UniquePtr<ChannelEvent>> mUnknownDecoderEventQ;
   bool mUnknownDecoderInvolved;
 
   bool mCanceled;
@@ -142,14 +153,14 @@ class FTPChannelChild final : public PFT
   // Once set, no OnStart/OnData/OnStop callbacks should be received from the
   // parent channel, nor dequeued from the ChannelEventQueue.
   bool mFlushedForDiversion;
   // Set if SendSuspend is called. Determines if SendResume is needed when
   // diverting callbacks to parent.
   bool mSuspendSent;
 };
 
-inline bool FTPChannelChild::IsSuspended() const { return mSuspendCount != 0; }
+inline bool FTPChannelChild::IsSuspended() { return mSuspendCount != 0; }
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // mozilla_net_FTPChannelChild_h
--- a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
@@ -226,16 +226,145 @@ IPCResult HttpBackgroundChannelChild::Re
     return IPC_OK();
   }
 
   mChannelChild->ProcessDivertMessages();
 
   return IPC_OK();
 }
 
+IPCResult
+HttpBackgroundChannelChild::RecvNotifyChannelClassifierProtectionDisabled(
+    const uint32_t& aAcceptedReason) {
+  LOG(
+      ("HttpBackgroundChannelChild::"
+       "RecvNotifyChannelClassifierProtectionDisabled [this=%p "
+       "aAcceptedReason=%" PRIu32 "]\n",
+       this, aAcceptedReason));
+  MOZ_ASSERT(OnSocketThread());
+
+  if (NS_WARN_IF(!mChannelChild)) {
+    return IPC_OK();
+  }
+
+  // NotifyChannelClassifierProtectionDisabled has no order dependency to
+  // OnStartRequest. It this be handled as soon as possible
+  mChannelChild->ProcessNotifyChannelClassifierProtectionDisabled(
+      aAcceptedReason);
+
+  return IPC_OK();
+}
+
+IPCResult HttpBackgroundChannelChild::RecvNotifyCookieAllowed() {
+  LOG(("HttpBackgroundChannelChild::RecvNotifyCookieAllowed [this=%p]\n",
+       this));
+  MOZ_ASSERT(OnSocketThread());
+
+  if (NS_WARN_IF(!mChannelChild)) {
+    return IPC_OK();
+  }
+
+  mChannelChild->ProcessNotifyCookieAllowed();
+
+  return IPC_OK();
+}
+
+IPCResult HttpBackgroundChannelChild::RecvNotifyCookieBlocked(
+    const uint32_t& aRejectedReason) {
+  LOG(
+      ("HttpBackgroundChannelChild::RecvNotifyCookieBlocked [this=%p "
+       "aRejectedReason=%" PRIu32 "]\n",
+       this, aRejectedReason));
+  MOZ_ASSERT(OnSocketThread());
+
+  if (NS_WARN_IF(!mChannelChild)) {
+    return IPC_OK();
+  }
+
+  mChannelChild->ProcessNotifyCookieBlocked(aRejectedReason);
+
+  return IPC_OK();
+}
+
+IPCResult HttpBackgroundChannelChild::RecvNotifyClassificationFlags(
+    const uint32_t& aClassificationFlags, const bool& aIsThirdParty) {
+  LOG(
+      ("HttpBackgroundChannelChild::RecvNotifyClassificationFlags "
+       "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n",
+       aClassificationFlags, static_cast<int>(aIsThirdParty), this));
+  MOZ_ASSERT(OnSocketThread());
+
+  if (NS_WARN_IF(!mChannelChild)) {
+    return IPC_OK();
+  }
+
+  // NotifyClassificationFlags has no order dependency to OnStartRequest.
+  // It this be handled as soon as possible
+  mChannelChild->ProcessNotifyClassificationFlags(aClassificationFlags,
+                                                  aIsThirdParty);
+
+  return IPC_OK();
+}
+
+IPCResult HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged(
+    const nsIHttpChannel::FlashPluginState& aState) {
+  LOG(
+      ("HttpBackgroundChannelChild::RecvNotifyFlashPluginStateChanged "
+       "[this=%p]\n",
+       this));
+  MOZ_ASSERT(OnSocketThread());
+
+  if (NS_WARN_IF(!mChannelChild)) {
+    return IPC_OK();
+  }
+
+  // NotifyFlashPluginStateChanged has no order dependency to OnStartRequest.
+  // It this be handled as soon as possible
+  mChannelChild->ProcessNotifyFlashPluginStateChanged(aState);
+
+  return IPC_OK();
+}
+
+IPCResult HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo(
+    const ClassifierInfo& info) {
+  LOG(("HttpBackgroundChannelChild::RecvSetClassifierMatchedInfo [this=%p]\n",
+       this));
+  MOZ_ASSERT(OnSocketThread());
+
+  if (NS_WARN_IF(!mChannelChild)) {
+    return IPC_OK();
+  }
+
+  // SetClassifierMatchedInfo has no order dependency to OnStartRequest.
+  // It this be handled as soon as possible
+  mChannelChild->ProcessSetClassifierMatchedInfo(info.list(), info.provider(),
+                                                 info.fullhash());
+
+  return IPC_OK();
+}
+
+IPCResult HttpBackgroundChannelChild::RecvSetClassifierMatchedTrackingInfo(
+    const ClassifierInfo& info) {
+  LOG(
+      ("HttpBackgroundChannelChild::RecvSetClassifierMatchedTrackingInfo "
+       "[this=%p]\n",
+       this));
+  MOZ_ASSERT(OnSocketThread());
+
+  if (NS_WARN_IF(!mChannelChild)) {
+    return IPC_OK();
+  }
+
+  // SetClassifierMatchedTrackingInfo has no order dependency to OnStartRequest.
+  // It this be handled as soon as possible
+  mChannelChild->ProcessSetClassifierMatchedTrackingInfo(info.list(),
+                                                         info.fullhash());
+
+  return IPC_OK();
+}
 void HttpBackgroundChannelChild::ActorDestroy(ActorDestroyReason aWhy) {
   LOG(("HttpBackgroundChannelChild::ActorDestroy[this=%p]\n", this));
   // This function might be called during shutdown phase, so OnSocketThread()
   // might return false even on STS thread. Use IsOnCurrentThreadInfallible()
   // to get correct information.
   MOZ_ASSERT(gSocketTransportService);
   MOZ_ASSERT(gSocketTransportService->IsOnCurrentThreadInfallible());
 
--- a/netwerk/protocol/http/HttpBackgroundChannelChild.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.h
@@ -7,16 +7,17 @@
 
 #ifndef mozilla_net_HttpBackgroundChannelChild_h
 #define mozilla_net_HttpBackgroundChannelChild_h
 
 #include "mozilla/net/PHttpBackgroundChannelChild.h"
 #include "nsIRunnable.h"
 #include "nsTArray.h"
 
+using mozilla::dom::ClassifierInfo;
 using mozilla::ipc::IPCResult;
 
 namespace mozilla {
 namespace net {
 
 class HttpChannelChild;
 
 class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
@@ -53,16 +54,33 @@ class HttpBackgroundChannelChild final :
                               const nsHttpHeaderArray& aResponseTrailers);
 
   IPCResult RecvFlushedForDiversion();
 
   IPCResult RecvDivertMessages();
 
   IPCResult RecvOnStartRequestSent();
 
+  IPCResult RecvNotifyChannelClassifierProtectionDisabled(
+      const uint32_t& aAcceptedReason);
+
+  IPCResult RecvNotifyCookieAllowed();
+
+  IPCResult RecvNotifyCookieBlocked(const uint32_t& aRejectedReason);
+
+  IPCResult RecvNotifyClassificationFlags(const uint32_t& aClassificationFlags,
+                                          const bool& aIsThirdParty);
+
+  IPCResult RecvNotifyFlashPluginStateChanged(
+      const nsIHttpChannel::FlashPluginState& aState);
+
+  IPCResult RecvSetClassifierMatchedInfo(const ClassifierInfo& info);
+
+  IPCResult RecvSetClassifierMatchedTrackingInfo(const ClassifierInfo& info);
+
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
  private:
   virtual ~HttpBackgroundChannelChild();
 
   // Initiate the creation of the PBckground IPC channel.
   // Return false if failed.
   bool CreateBackgroundChannel();
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.cpp
@@ -258,16 +258,233 @@ bool HttpBackgroundChannelParent::OnDive
   // the OnDataAvailables and OnStopRequest to associated HttpChannelParent.
   if (!SendDivertMessages()) {
     return false;
   }
 
   return true;
 }
 
+bool HttpBackgroundChannelParent::OnNotifyChannelClassifierProtectionDisabled(
+    uint32_t aAcceptedReason) {
+  LOG(
+      ("HttpBackgroundChannelParent::"
+       "OnNotifyChannelClassifierProtectionDisabled [this=%p - "
+       "aAcceptedReason=%" PRIu32 "]\n",
+       this, aAcceptedReason));
+  AssertIsInMainProcess();
+
+  if (NS_WARN_IF(!mIPCOpened)) {
+    return false;
+  }
+
+  if (!IsOnBackgroundThread()) {
+    MutexAutoLock lock(mBgThreadMutex);
+    RefPtr<HttpBackgroundChannelParent> self = this;
+    nsresult rv = mBackgroundThread->Dispatch(
+        NS_NewRunnableFunction(
+            "net::HttpBackgroundChannelParent::"
+            "OnNotifyChannelClassifierProtectionDisabled",
+            [self, aAcceptedReason]() {
+              self->OnNotifyChannelClassifierProtectionDisabled(
+                  aAcceptedReason);
+            }),
+        NS_DISPATCH_NORMAL);
+
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+    return NS_SUCCEEDED(rv);
+  }
+
+  return SendNotifyChannelClassifierProtectionDisabled(aAcceptedReason);
+}
+
+bool HttpBackgroundChannelParent::OnNotifyCookieAllowed() {
+  LOG(("HttpBackgroundChannelParent::OnNotifyCookieAllowed [this=%p]\n", this));
+  AssertIsInMainProcess();
+
+  if (NS_WARN_IF(!mIPCOpened)) {
+    return false;
+  }
+
+  if (!IsOnBackgroundThread()) {
+    MutexAutoLock lock(mBgThreadMutex);
+    RefPtr<HttpBackgroundChannelParent> self = this;
+    nsresult rv = mBackgroundThread->Dispatch(
+        NS_NewRunnableFunction(
+            "net::HttpBackgroundChannelParent::OnNotifyCookieAllowed",
+            [self]() { self->OnNotifyCookieAllowed(); }),
+        NS_DISPATCH_NORMAL);
+
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+    return NS_SUCCEEDED(rv);
+  }
+
+  return SendNotifyCookieAllowed();
+}
+
+bool HttpBackgroundChannelParent::OnNotifyCookieBlocked(
+    uint32_t aRejectedReason) {
+  LOG(
+      ("HttpBackgroundChannelParent::OnNotifyCookieBlocked [this=%p "
+       "aRejectedReason=%" PRIu32 "]\n",
+       this, aRejectedReason));
+  AssertIsInMainProcess();
+
+  if (NS_WARN_IF(!mIPCOpened)) {
+    return false;
+  }
+
+  if (!IsOnBackgroundThread()) {
+    MutexAutoLock lock(mBgThreadMutex);
+    RefPtr<HttpBackgroundChannelParent> self = this;
+    nsresult rv = mBackgroundThread->Dispatch(
+        NS_NewRunnableFunction(
+            "net::HttpBackgroundChannelParent::OnNotifyCookieBlocked",
+            [self, aRejectedReason]() {
+              self->OnNotifyCookieBlocked(aRejectedReason);
+            }),
+        NS_DISPATCH_NORMAL);
+
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+    return NS_SUCCEEDED(rv);
+  }
+
+  return SendNotifyCookieBlocked(aRejectedReason);
+}
+
+bool HttpBackgroundChannelParent::OnNotifyClassificationFlags(
+    uint32_t aClassificationFlags, bool aIsThirdParty) {
+  LOG(
+      ("HttpBackgroundChannelParent::OnNotifyClassificationFlags "
+       "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n",
+       aClassificationFlags, static_cast<int>(aIsThirdParty), this));
+  AssertIsInMainProcess();
+
+  if (NS_WARN_IF(!mIPCOpened)) {
+    return false;
+  }
+
+  if (!IsOnBackgroundThread()) {
+    MutexAutoLock lock(mBgThreadMutex);
+    nsresult rv = mBackgroundThread->Dispatch(
+        NewRunnableMethod<uint32_t, bool>(
+            "net::HttpBackgroundChannelParent::OnNotifyClassificationFlags",
+            this, &HttpBackgroundChannelParent::OnNotifyClassificationFlags,
+            aClassificationFlags, aIsThirdParty),
+        NS_DISPATCH_NORMAL);
+
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+    return NS_SUCCEEDED(rv);
+  }
+
+  return SendNotifyClassificationFlags(aClassificationFlags, aIsThirdParty);
+}
+
+bool HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged(
+    nsIHttpChannel::FlashPluginState aState) {
+  LOG(
+      ("HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged "
+       "[this=%p]\n",
+       this));
+  AssertIsInMainProcess();
+
+  if (NS_WARN_IF(!mIPCOpened)) {
+    return false;
+  }
+
+  if (!IsOnBackgroundThread()) {
+    MutexAutoLock lock(mBgThreadMutex);
+    RefPtr<HttpBackgroundChannelParent> self = this;
+    nsresult rv = mBackgroundThread->Dispatch(
+        NS_NewRunnableFunction(
+            "net::HttpBackgroundChannelParent::OnNotifyFlashPluginStateChanged",
+            [self, aState]() {
+              self->OnNotifyFlashPluginStateChanged(aState);
+            }),
+        NS_DISPATCH_NORMAL);
+
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+    return NS_SUCCEEDED(rv);
+  }
+
+  return SendNotifyFlashPluginStateChanged(aState);
+}
+
+bool HttpBackgroundChannelParent::OnSetClassifierMatchedInfo(
+    const nsACString& aList, const nsACString& aProvider,
+    const nsACString& aFullHash) {
+  LOG(("HttpBackgroundChannelParent::OnSetClassifierMatchedInfo [this=%p]\n",
+       this));
+  AssertIsInMainProcess();
+
+  if (NS_WARN_IF(!mIPCOpened)) {
+    return false;
+  }
+
+  if (!IsOnBackgroundThread()) {
+    MutexAutoLock lock(mBgThreadMutex);
+    nsresult rv = mBackgroundThread->Dispatch(
+        NewRunnableMethod<const nsCString, const nsCString, const nsCString>(
+            "net::HttpBackgroundChannelParent::OnSetClassifierMatchedInfo",
+            this, &HttpBackgroundChannelParent::OnSetClassifierMatchedInfo,
+            aList, aProvider, aFullHash),
+        NS_DISPATCH_NORMAL);
+
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+    return NS_SUCCEEDED(rv);
+  }
+
+  ClassifierInfo info;
+  info.list() = aList;
+  info.fullhash() = aFullHash;
+  info.provider() = aProvider;
+
+  return SendSetClassifierMatchedInfo(info);
+}
+
+bool HttpBackgroundChannelParent::OnSetClassifierMatchedTrackingInfo(
+    const nsACString& aLists, const nsACString& aFullHashes) {
+  LOG(
+      ("HttpBackgroundChannelParent::OnSetClassifierMatchedTrackingInfo "
+       "[this=%p]\n",
+       this));
+  AssertIsInMainProcess();
+
+  if (NS_WARN_IF(!mIPCOpened)) {
+    return false;
+  }
+
+  if (!IsOnBackgroundThread()) {
+    MutexAutoLock lock(mBgThreadMutex);
+    nsresult rv = mBackgroundThread->Dispatch(
+        NewRunnableMethod<const nsCString, const nsCString>(
+            "net::HttpBackgroundChannelParent::"
+            "OnSetClassifierMatchedTrackingInfo",
+            this,
+            &HttpBackgroundChannelParent::OnSetClassifierMatchedTrackingInfo,
+            aLists, aFullHashes),
+        NS_DISPATCH_NORMAL);
+
+    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
+
+    return NS_SUCCEEDED(rv);
+  }
+
+  ClassifierInfo info;
+  info.list() = aLists;
+  info.fullhash() = aFullHashes;
+
+  return SendSetClassifierMatchedTrackingInfo(info);
+}
 void HttpBackgroundChannelParent::ActorDestroy(ActorDestroyReason aWhy) {
   LOG(("HttpBackgroundChannelParent::ActorDestroy [this=%p]\n", this));
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
 
   mIPCOpened = false;
 
   RefPtr<HttpBackgroundChannelParent> self = this;
--- a/netwerk/protocol/http/HttpBackgroundChannelParent.h
+++ b/netwerk/protocol/http/HttpBackgroundChannelParent.h
@@ -52,16 +52,42 @@ class HttpBackgroundChannelParent final 
   bool OnStopRequest(const nsresult& aChannelStatus,
                      const ResourceTimingStruct& aTiming,
                      const nsHttpHeaderArray& aResponseTrailers);
 
   // To send FlushedForDiversion and DivertMessages messages
   // over background channel.
   bool OnDiversion();
 
+  // To send NotifyChannelClassifierProtectionDisabled message over background
+  // channel.
+  bool OnNotifyChannelClassifierProtectionDisabled(uint32_t aAcceptedReason);
+
+  // To send NotifyCookieAllowed message over background channel.
+  bool OnNotifyCookieAllowed();
+
+  // To send NotifyCookieBlocked message over background channel.
+  bool OnNotifyCookieBlocked(uint32_t aRejectedReason);
+
+  // To send NotifyClassificationFlags message over background channel.
+  bool OnNotifyClassificationFlags(uint32_t aClassificationFlags,
+                                   bool aIsThirdParty);
+
+  // To send NotifyFlashPluginStateChanged message over background channel.
+  bool OnNotifyFlashPluginStateChanged(nsIHttpChannel::FlashPluginState aState);
+
+  // To send SetClassifierMatchedInfo message over background channel.
+  bool OnSetClassifierMatchedInfo(const nsACString& aList,
+                                  const nsACString& aProvider,
+                                  const nsACString& aFullHash);
+
+  // To send SetClassifierMatchedTrackingInfo message over background channel.
+  bool OnSetClassifierMatchedTrackingInfo(const nsACString& aLists,
+                                          const nsACString& aFullHashes);
+
  protected:
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
  private:
   virtual ~HttpBackgroundChannelParent();
 
   Atomic<bool> mIPCOpened;
 
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -340,71 +340,163 @@ void HttpChannelChild::OnBackgroundChild
   }
 
   if (callback) {
     nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
     neckoTarget->Dispatch(callback, NS_DISPATCH_NORMAL);
   }
 }
 
+class AssociateApplicationCacheEvent
+    : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  AssociateApplicationCacheEvent(HttpChannelChild* aChild,
+                                 const nsCString& aGroupID,
+                                 const nsCString& aClientID)
+      : NeckoTargetChannelEvent<HttpChannelChild>(aChild),
+        groupID(aGroupID),
+        clientID(aClientID) {}
+
+  void Run() override { mChild->AssociateApplicationCache(groupID, clientID); }
+
+ private:
+  nsCString groupID;
+  nsCString clientID;
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvAssociateApplicationCache(
-    const nsCString& aGroupID, const nsCString& aClientID) {
+    const nsCString& groupID, const nsCString& clientID) {
   LOG(("HttpChannelChild::RecvAssociateApplicationCache [this=%p]\n", this));
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=]() { self->AssociateApplicationCache(aGroupID, aClientID); }));
+  mEventQ->RunOrEnqueue(
+      new AssociateApplicationCacheEvent(this, groupID, clientID));
   return IPC_OK();
 }
 
-void HttpChannelChild::AssociateApplicationCache(const nsCString& aGroupID,
-                                                 const nsCString& aClientID) {
+void HttpChannelChild::AssociateApplicationCache(const nsCString& groupID,
+                                                 const nsCString& clientID) {
   LOG(("HttpChannelChild::AssociateApplicationCache [this=%p]\n", this));
   mApplicationCache = new nsApplicationCache();
 
   mLoadedFromApplicationCache = true;
-  mApplicationCache->InitAsHandle(aGroupID, aClientID);
+  mApplicationCache->InitAsHandle(groupID, clientID);
 }
 
+class StartRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  StartRequestEvent(
+      HttpChannelChild* aChild, const nsresult& aChannelStatus,
+      const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead,
+      const nsHttpHeaderArray& aRequestHeaders,
+      const ParentLoadInfoForwarderArgs& loadInfoForwarder,
+      const bool& aIsFromCache, const bool& aIsRacing,
+      const bool& aCacheEntryAvailable, const uint64_t& aCacheEntryId,
+      const int32_t& aCacheFetchCount, const uint32_t& aCacheExpirationTime,
+      const nsCString& aCachedCharset,
+      const nsCString& aSecurityInfoSerialization, const NetAddr& aSelfAddr,
+      const NetAddr& aPeerAddr, const uint32_t& aCacheKey,
+      const nsCString& altDataType, const int64_t& altDataLen,
+      const bool& deliveringAltData, const bool& aApplyConversion,
+      const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming,
+      const bool& aAllRedirectsSameOrigin)
+      : NeckoTargetChannelEvent<HttpChannelChild>(aChild),
+        mChannelStatus(aChannelStatus),
+        mResponseHead(aResponseHead),
+        mRequestHeaders(aRequestHeaders),
+        mUseResponseHead(aUseResponseHead),
+        mApplyConversion(aApplyConversion),
+        mIsFromCache(aIsFromCache),
+        mIsRacing(aIsRacing),
+        mCacheEntryAvailable(aCacheEntryAvailable),
+        mCacheEntryId(aCacheEntryId),
+        mCacheFetchCount(aCacheFetchCount),
+        mCacheExpirationTime(aCacheExpirationTime),
+        mCachedCharset(aCachedCharset),
+        mSecurityInfoSerialization(aSecurityInfoSerialization),
+        mSelfAddr(aSelfAddr),
+        mPeerAddr(aPeerAddr),
+        mCacheKey(aCacheKey),
+        mAltDataType(altDataType),
+        mAltDataLen(altDataLen),
+        mDeliveringAltData(deliveringAltData),
+        mLoadInfoForwarder(loadInfoForwarder),
+        mIsResolvedByTRR(aIsResolvedByTRR),
+        mTiming(aTiming),
+        mAllRedirectsSameOrigin(aAllRedirectsSameOrigin) {}
+
+  void Run() override {
+    LOG(("StartRequestEvent [this=%p]\n", mChild));
+    mChild->OnStartRequest(
+        mChannelStatus, mResponseHead, mUseResponseHead, mRequestHeaders,
+        mLoadInfoForwarder, mIsFromCache, mIsRacing, mCacheEntryAvailable,
+        mCacheEntryId, mCacheFetchCount, mCacheExpirationTime, mCachedCharset,
+        mSecurityInfoSerialization, mSelfAddr, mPeerAddr, mCacheKey,
+        mAltDataType, mAltDataLen, mDeliveringAltData, mApplyConversion,
+        mIsResolvedByTRR, mTiming, mAllRedirectsSameOrigin);
+  }
+
+ private:
+  nsresult mChannelStatus;
+  nsHttpResponseHead mResponseHead;
+  nsHttpHeaderArray mRequestHeaders;
+  bool mUseResponseHead;
+  bool mApplyConversion;
+  bool mIsFromCache;
+  bool mIsRacing;
+  bool mCacheEntryAvailable;
+  uint64_t mCacheEntryId;
+  int32_t mCacheFetchCount;
+  uint32_t mCacheExpirationTime;
+  nsCString mCachedCharset;
+  nsCString mSecurityInfoSerialization;
+  NetAddr mSelfAddr;
+  NetAddr mPeerAddr;
+  uint32_t mCacheKey;
+  nsCString mAltDataType;
+  int64_t mAltDataLen;
+  bool mDeliveringAltData;
+  ParentLoadInfoForwarderArgs mLoadInfoForwarder;
+  bool mIsResolvedByTRR;
+  ResourceTimingStruct mTiming;
+  bool mAllRedirectsSameOrigin;
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvOnStartRequest(
-    const nsresult& aChannelStatus, const nsHttpResponseHead& aResponseHead,
-    const bool& aUseResponseHead, const nsHttpHeaderArray& aRequestHeaders,
-    const ParentLoadInfoForwarderArgs& aLoadInfoForwarder,
-    const bool& aIsFromCache, const bool& aIsRacing,
-    const bool& aCacheEntryAvailable, const uint64_t& aCacheEntryId,
-    const int32_t& aCacheFetchCount, const uint32_t& aCacheExpirationTime,
-    const nsCString& aCachedCharset, const nsCString& aSecurityInfoSerialization,
-    const NetAddr& aSelfAddr, const NetAddr& aPeerAddr,
-    const int16_t& aRedirectCount, const uint32_t& aCacheKey,
-    const nsCString& aAltDataType, const int64_t& aAltDataLen,
-    const bool& aDeliveringAltData, const bool& aApplyConversion,
+    const nsresult& channelStatus, const nsHttpResponseHead& responseHead,
+    const bool& useResponseHead, const nsHttpHeaderArray& requestHeaders,
+    const ParentLoadInfoForwarderArgs& loadInfoForwarder,
+    const bool& isFromCache, const bool& isRacing,
+    const bool& cacheEntryAvailable, const uint64_t& cacheEntryId,
+    const int32_t& cacheFetchCount, const uint32_t& cacheExpirationTime,
+    const nsCString& cachedCharset, const nsCString& securityInfoSerialization,
+    const NetAddr& selfAddr, const NetAddr& peerAddr,
+    const int16_t& redirectCount, const uint32_t& cacheKey,
+    const nsCString& altDataType, const int64_t& altDataLen,
+    const bool& deliveringAltData, const bool& aApplyConversion,
     const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming,
     const bool& aAllRedirectsSameOrigin) {
   AUTO_PROFILER_LABEL("HttpChannelChild::RecvOnStartRequest", NETWORK);
   LOG(("HttpChannelChild::RecvOnStartRequest [this=%p]\n", this));
   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
   // stage, as they are set in the listener's OnStartRequest.
   MOZ_RELEASE_ASSERT(
       !mFlushedForDiversion,
       "mFlushedForDiversion should be unset before OnStartRequest!");
   MOZ_RELEASE_ASSERT(
       !mDivertingToParent,
       "mDivertingToParent should be unset before OnStartRequest!");
 
-  mRedirectCount = aRedirectCount;
-
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=]() {
-    self->OnStartRequest(
-        aChannelStatus, aResponseHead, aUseResponseHead, aRequestHeaders,
-        aLoadInfoForwarder, aIsFromCache, aIsRacing, aCacheEntryAvailable,
-        aCacheEntryId, aCacheFetchCount, aCacheExpirationTime, aCachedCharset,
-        aSecurityInfoSerialization, aSelfAddr, aPeerAddr, aCacheKey, aAltDataType,
-        aAltDataLen, aDeliveringAltData, aApplyConversion, aIsResolvedByTRR,
-        aTiming, aAllRedirectsSameOrigin);
-  }));
+  mRedirectCount = redirectCount;
+
+  mEventQ->RunOrEnqueue(new StartRequestEvent(
+      this, channelStatus, responseHead, useResponseHead, requestHeaders,
+      loadInfoForwarder, isFromCache, isRacing, cacheEntryAvailable,
+      cacheEntryId, cacheFetchCount, cacheExpirationTime, cachedCharset,
+      securityInfoSerialization, selfAddr, peerAddr, cacheKey, altDataType,
+      altDataLen, deliveringAltData, aApplyConversion, aIsResolvedByTRR,
+      aTiming, aAllRedirectsSameOrigin));
 
   {
     // Child's mEventQ is to control the execution order of the IPC messages
     // from both main thread IPDL and PBackground IPDL.
     // To guarantee the ordering, PBackground IPC messages that are sent after
     // OnStartRequest will be throttled until OnStartRequest hits the Child's
     // mEventQ.
     MutexAutoLock lock(mBgChildMutex);
@@ -418,26 +510,26 @@ mozilla::ipc::IPCResult HttpChannelChild
           NS_DISPATCH_NORMAL);
     }
   }
 
   return IPC_OK();
 }
 
 void HttpChannelChild::OnStartRequest(
-    const nsresult& aChannelStatus, const nsHttpResponseHead& aResponseHead,
-    const bool& aUseResponseHead, const nsHttpHeaderArray& aRequestHeaders,
-    const ParentLoadInfoForwarderArgs& aLoadInfoForwarder,
-    const bool& aIsFromCache, const bool& aIsRacing,
-    const bool& aCacheEntryAvailable, const uint64_t& aCacheEntryId,
-    const int32_t& aCacheFetchCount, const uint32_t& aCacheExpirationTime,
-    const nsCString& aCachedCharset, const nsCString& aSecurityInfoSerialization,
-    const NetAddr& aSelfAddr, const NetAddr& aPeerAddr, const uint32_t& aCacheKey,
-    const nsCString& aAltDataType, const int64_t& aAltDataLen,
-    const bool& aDeliveringAltData, const bool& aApplyConversion,
+    const nsresult& channelStatus, const nsHttpResponseHead& responseHead,
+    const bool& useResponseHead, const nsHttpHeaderArray& requestHeaders,
+    const ParentLoadInfoForwarderArgs& loadInfoForwarder,
+    const bool& isFromCache, const bool& isRacing,
+    const bool& cacheEntryAvailable, const uint64_t& cacheEntryId,
+    const int32_t& cacheFetchCount, const uint32_t& cacheExpirationTime,
+    const nsCString& cachedCharset, const nsCString& securityInfoSerialization,
+    const NetAddr& selfAddr, const NetAddr& peerAddr, const uint32_t& cacheKey,
+    const nsCString& altDataType, const int64_t& altDataLen,
+    const bool& deliveringAltData, const bool& aApplyConversion,
     const bool& aIsResolvedByTRR, const ResourceTimingStruct& aTiming,
     const bool& aAllRedirectsSameOrigin) {
   LOG(("HttpChannelChild::OnStartRequest [this=%p]\n", this));
 
   // mFlushedForDiversion and mDivertingToParent should NEVER be set at this
   // stage, as they are set in the listener's OnStartRequest.
   MOZ_RELEASE_ASSERT(
       !mFlushedForDiversion,
@@ -450,61 +542,61 @@ void HttpChannelChild::OnStartRequest(
   // OnStartRequest/OnStopRequest/OnDataAvailable IPC messages that need to
   // be handled. In that case we just ignore them to avoid calling the listener
   // twice.
   if (mOnStartRequestCalled && mIPCActorDeleted) {
     return;
   }
 
   if (!mCanceled && NS_SUCCEEDED(mStatus)) {
-    mStatus = aChannelStatus;
+    mStatus = channelStatus;
   }
 
   // Cookies headers should not be visible to the child process
-  MOZ_ASSERT(!aRequestHeaders.HasHeader(nsHttp::Cookie));
-  MOZ_ASSERT(!nsHttpResponseHead(aResponseHead).HasHeader(nsHttp::Set_Cookie));
-
-  if (aUseResponseHead && !mCanceled)
-    mResponseHead = new nsHttpResponseHead(aResponseHead);
-
-  if (!aSecurityInfoSerialization.IsEmpty()) {
-    nsresult rv = NS_DeserializeObject(aSecurityInfoSerialization,
+  MOZ_ASSERT(!requestHeaders.HasHeader(nsHttp::Cookie));
+  MOZ_ASSERT(!nsHttpResponseHead(responseHead).HasHeader(nsHttp::Set_Cookie));
+
+  if (useResponseHead && !mCanceled)
+    mResponseHead = new nsHttpResponseHead(responseHead);
+
+  if (!securityInfoSerialization.IsEmpty()) {
+    nsresult rv = NS_DeserializeObject(securityInfoSerialization,
                                        getter_AddRefs(mSecurityInfo));
     MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv),
                           "Deserializing security info should not fail");
     Unused << rv;  // So we don't get an unused error in release builds.
   }
 
-  ipc::MergeParentLoadInfoForwarder(aLoadInfoForwarder, mLoadInfo);
-
-  mIsFromCache = aIsFromCache;
-  mIsRacing = aIsRacing;
-  mCacheEntryAvailable = aCacheEntryAvailable;
-  mCacheEntryId = aCacheEntryId;
-  mCacheFetchCount = aCacheFetchCount;
-  mCacheExpirationTime = aCacheExpirationTime;
-  mCachedCharset = aCachedCharset;
-  mSelfAddr = aSelfAddr;
-  mPeerAddr = aPeerAddr;
-
-  mAvailableCachedAltDataType = aAltDataType;
-  mDeliveringAltData = aDeliveringAltData;
-  mAltDataLength = aAltDataLen;
+  ipc::MergeParentLoadInfoForwarder(loadInfoForwarder, mLoadInfo);
+
+  mIsFromCache = isFromCache;
+  mIsRacing = isRacing;
+  mCacheEntryAvailable = cacheEntryAvailable;
+  mCacheEntryId = cacheEntryId;
+  mCacheFetchCount = cacheFetchCount;
+  mCacheExpirationTime = cacheExpirationTime;
+  mCachedCharset = cachedCharset;
+  mSelfAddr = selfAddr;
+  mPeerAddr = peerAddr;
+
+  mAvailableCachedAltDataType = altDataType;
+  mDeliveringAltData = deliveringAltData;
+  mAltDataLength = altDataLen;
   mResolvedByTRR = aIsResolvedByTRR;
 
   SetApplyConversion(aApplyConversion);
 
   mAfterOnStartRequestBegun = true;
 
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
-  mCacheKey = aCacheKey;
+  mCacheKey = cacheKey;
 
   // replace our request headers with what actually got sent in the parent
-  mRequestHead.SetHeaders(aRequestHeaders);
+  mRequestHead.SetHeaders(requestHeaders);
 
   // Note: this is where we would notify "http-on-examine-response" observers.
   // We have deliberately disabled this for child processes (see bug 806753)
   //
   // gHttpHandler->OnExamineResponse(this);
 
   mTracingEnabled = false;
 
@@ -621,135 +713,176 @@ void HttpChannelChild::DoOnStartRequest(
   if (NS_FAILED(rv)) {
     Cancel(rv);
   } else if (listener) {
     mListener = listener;
     mCompressListener = listener;
   }
 }
 
+class TransportAndDataEvent : public ChannelEvent {
+ public:
+  TransportAndDataEvent(HttpChannelChild* child, const nsresult& channelStatus,
+                        const nsresult& transportStatus, const nsCString& data,
+                        const uint64_t& offset, const uint32_t& count)
+      : mChild(child),
+        mChannelStatus(channelStatus),
+        mTransportStatus(transportStatus),
+        mData(data),
+        mOffset(offset),
+        mCount(count) {}
+
+  void Run() override {
+    mChild->OnTransportAndData(mChannelStatus, mTransportStatus, mOffset,
+                               mCount, mData);
+  }
+
+  already_AddRefed<nsIEventTarget> GetEventTarget() override {
+    MOZ_ASSERT(mChild);
+    nsCOMPtr<nsIEventTarget> target = mChild->GetODATarget();
+    return target.forget();
+  }
+
+ private:
+  HttpChannelChild* mChild;
+  nsresult mChannelStatus;
+  nsresult mTransportStatus;
+  nsCString mData;
+  uint64_t mOffset;
+  uint32_t mCount;
+};
+
 void HttpChannelChild::ProcessOnTransportAndData(
     const nsresult& aChannelStatus, const nsresult& aTransportStatus,
     const uint64_t& aOffset, const uint32_t& aCount, const nsCString& aData) {
   LOG(("HttpChannelChild::ProcessOnTransportAndData [this=%p]\n", this));
   MOZ_ASSERT(OnSocketThread());
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
                      "Should not be receiving any more callbacks from parent!");
-  RefPtr<HttpChannelChild> self = this;
   mEventQ->RunOrEnqueue(
-      new ChannelFunctionEvent([self]() { return self->GetODATarget(); },
-                               [=]() {
-                                 self->OnTransportAndData(
-                                     aChannelStatus, aTransportStatus, aOffset,
-                                     aCount, aData);
-                               }),
+      new TransportAndDataEvent(this, aChannelStatus, aTransportStatus, aData,
+                                aOffset, aCount),
       mDivertingToParent);
 }
 
-void HttpChannelChild::MaybeDivertOnData(const nsCString& aData,
-                                         const uint64_t& aOffset,
-                                         const uint32_t& aCount) {
+class MaybeDivertOnDataHttpEvent
+    : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  MaybeDivertOnDataHttpEvent(HttpChannelChild* child, const nsCString& data,
+                             const uint64_t& offset, const uint32_t& count)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child),
+        mData(data),
+        mOffset(offset),
+        mCount(count) {}
+
+  void Run() override { mChild->MaybeDivertOnData(mData, mOffset, mCount); }
+
+ private:
+  nsCString mData;
+  uint64_t mOffset;
+  uint32_t mCount;
+};
+
+void HttpChannelChild::MaybeDivertOnData(const nsCString& data,
+                                         const uint64_t& offset,
+                                         const uint32_t& count) {
   LOG(("HttpChannelChild::MaybeDivertOnData [this=%p]", this));
 
   if (mDivertingToParent) {
-    SendDivertOnDataAvailable(aData, aOffset, aCount);
+    SendDivertOnDataAvailable(data, offset, count);
   }
 }
 
-void HttpChannelChild::OnTransportAndData(const nsresult& aChannelStatus,
-                                          const nsresult& aTransportStatus,
-                                          const uint64_t& aOffset,
-                                          const uint32_t& aCount,
-                                          const nsCString& aData) {
+void HttpChannelChild::OnTransportAndData(const nsresult& channelStatus,
+                                          const nsresult& transportStatus,
+                                          const uint64_t& offset,
+                                          const uint32_t& count,
+                                          const nsCString& data) {
   LOG(("HttpChannelChild::OnTransportAndData [this=%p]\n", this));
 
   if (!mCanceled && NS_SUCCEEDED(mStatus)) {
-    mStatus = aChannelStatus;
+    mStatus = channelStatus;
   }
 
   // For diversion to parent, just SendDivertOnDataAvailable.
   if (mDivertingToParent) {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_RELEASE_ASSERT(
         !mFlushedForDiversion,
         "Should not be processing any more callbacks from parent!");
 
-    SendDivertOnDataAvailable(aData, aOffset, aCount);
+    SendDivertOnDataAvailable(data, offset, count);
     return;
   }
 
-  if (mCanceled) {
-    return;
-  }
+  if (mCanceled) return;
 
   if (mUnknownDecoderInvolved) {
     LOG(("UnknownDecoder is involved queue OnDataAvailable call. [this=%p]",
          this));
     MOZ_ASSERT(NS_IsMainThread());
-    RefPtr<HttpChannelChild> self = this;
     mUnknownDecoderEventQ.AppendElement(
-        MakeUnique<NeckoTargetChannelFunctionEvent>(
-            this, [=]() { self->MaybeDivertOnData(aData, aOffset, aCount); }));
+        MakeUnique<MaybeDivertOnDataHttpEvent>(this, data, offset, count));
   }
 
   // Hold queue lock throughout all three calls, else we might process a later
   // necko msg in between them.
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
   int64_t progressMax;
   if (NS_FAILED(GetContentLength(&progressMax))) {
     progressMax = -1;
   }
 
-  const int64_t progress = aOffset + aCount;
+  const int64_t progress = offset + count;
 
   // OnTransportAndData will be run on retargeted thread if applicable, however
   // OnStatus/OnProgress event can only be fired on main thread. We need to
   // dispatch the status/progress event handling back to main thread with the
   // appropriate event target for networking.
   if (NS_IsMainThread()) {
-    DoOnStatus(this, aTransportStatus);
+    DoOnStatus(this, transportStatus);
     DoOnProgress(this, progress, progressMax);
   } else {
     RefPtr<HttpChannelChild> self = this;
     nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
     MOZ_ASSERT(neckoTarget);
 
     DebugOnly<nsresult> rv = neckoTarget->Dispatch(
         NS_NewRunnableFunction(
             "net::HttpChannelChild::OnTransportAndData",
-            [self, aTransportStatus, progress, progressMax]() {
-              self->DoOnStatus(self, aTransportStatus);
+            [self, transportStatus, progress, progressMax]() {
+              self->DoOnStatus(self, transportStatus);
               self->DoOnProgress(self, progress, progressMax);
             }),
         NS_DISPATCH_NORMAL);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
   }
 
   // OnDataAvailable
   //
   // NOTE: the OnDataAvailable contract requires the client to read all the data
   // in the inputstream.  This code relies on that ('data' will go away after
   // this function).  Apparently the previous, non-e10s behavior was to actually
   // support only reading part of the data, allowing later calls to read the
   // rest.
   nsCOMPtr<nsIInputStream> stringStream;
   nsresult rv =
       NS_NewByteInputStream(getter_AddRefs(stringStream),
-                            MakeSpan(aData).To(aCount), NS_ASSIGNMENT_DEPEND);
+                            MakeSpan(data).To(count), NS_ASSIGNMENT_DEPEND);
   if (NS_FAILED(rv)) {
     Cancel(rv);
     return;
   }
 
-  DoOnDataAvailable(this, nullptr, stringStream, aOffset, aCount);
+  DoOnDataAvailable(this, nullptr, stringStream, offset, count);
   stringStream->Close();
 
   if (NeedToReportBytesRead()) {
-    mUnreportBytesRead += aCount;
+    mUnreportBytesRead += count;
     if (mUnreportBytesRead >= gHttpHandler->SendWindowSize() >> 2) {
       if (NS_IsMainThread()) {
         Unused << SendBytesRead(mUnreportBytesRead);
       } else {
         // PHttpChannel connects to the main thread
         RefPtr<HttpChannelChild> self = this;
         int32_t bytesRead = mUnreportBytesRead;
         nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
@@ -829,145 +962,172 @@ void HttpChannelChild::DoOnProgress(nsIR
       mProgressSink->OnProgress(aRequest, nullptr, progress, progressMax);
     }
   }
 }
 
 void HttpChannelChild::DoOnDataAvailable(nsIRequest* aRequest,
                                          nsISupports* aContext,
                                          nsIInputStream* aStream,
-                                         uint64_t aOffset, uint32_t aCount) {
+                                         uint64_t offset, uint32_t count) {
   AUTO_PROFILER_LABEL("HttpChannelChild::DoOnDataAvailable", NETWORK);
   LOG(("HttpChannelChild::DoOnDataAvailable [this=%p]\n", this));
   if (mCanceled) return;
 
   if (mListener) {
     nsCOMPtr<nsIStreamListener> listener(mListener);
-    nsresult rv = listener->OnDataAvailable(aRequest, aStream, aOffset, aCount);
+    nsresult rv = listener->OnDataAvailable(aRequest, aStream, offset, count);
     if (NS_FAILED(rv)) {
       CancelOnMainThread(rv);
     }
   }
 }
 
+class StopRequestEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  StopRequestEvent(HttpChannelChild* child, const nsresult& channelStatus,
+                   const ResourceTimingStruct& timing,
+                   const nsHttpHeaderArray& aResponseTrailers)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child),
+        mChannelStatus(channelStatus),
+        mTiming(timing),
+        mResponseTrailers(aResponseTrailers) {}
+
+  void Run() override {
+    mChild->OnStopRequest(mChannelStatus, mTiming, mResponseTrailers);
+  }
+
+ private:
+  nsresult mChannelStatus;
+  ResourceTimingStruct mTiming;
+  nsHttpHeaderArray mResponseTrailers;
+};
+
 void HttpChannelChild::ProcessOnStopRequest(
     const nsresult& aChannelStatus, const ResourceTimingStruct& aTiming,
     const nsHttpHeaderArray& aResponseTrailers) {
   LOG(("HttpChannelChild::ProcessOnStopRequest [this=%p]\n", this));
   MOZ_ASSERT(OnSocketThread());
   MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
                      "Should not be receiving any more callbacks from parent!");
 
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-                            this,
-                            [=]() {
-                              self->OnStopRequest(aChannelStatus, aTiming,
-                                                  aResponseTrailers);
-                            }),
-                        mDivertingToParent);
+  mEventQ->RunOrEnqueue(
+      new StopRequestEvent(this, aChannelStatus, aTiming, aResponseTrailers),
+      mDivertingToParent);
 }
 
+class MaybeDivertOnStopHttpEvent
+    : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  MaybeDivertOnStopHttpEvent(HttpChannelChild* child,
+                             const nsresult& channelStatus)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child),
+        mChannelStatus(channelStatus) {}
+
+  void Run() override { mChild->MaybeDivertOnStop(mChannelStatus); }
+
+ private:
+  nsresult mChannelStatus;
+};
+
 void HttpChannelChild::MaybeDivertOnStop(const nsresult& aChannelStatus) {
   LOG(
       ("HttpChannelChild::MaybeDivertOnStop [this=%p, "
        "mDivertingToParent=%d status=%" PRIx32 "]",
        this, static_cast<bool>(mDivertingToParent),
        static_cast<uint32_t>(aChannelStatus)));
   if (mDivertingToParent) {
     SendDivertOnStopRequest(aChannelStatus);
   }
 }
 
 void HttpChannelChild::OnStopRequest(
-    const nsresult& aChannelStatus, const ResourceTimingStruct& aTiming,
+    const nsresult& channelStatus, const ResourceTimingStruct& timing,
     const nsHttpHeaderArray& aResponseTrailers) {
   LOG(("HttpChannelChild::OnStopRequest [this=%p status=%" PRIx32 "]\n", this,
-       static_cast<uint32_t>(aChannelStatus)));
+       static_cast<uint32_t>(channelStatus)));
   MOZ_ASSERT(NS_IsMainThread());
 
   // If this channel was aborted by ActorDestroy, then there may be other
   // OnStartRequest/OnStopRequest/OnDataAvailable IPC messages that need to
   // be handled. In that case we just ignore them to avoid calling the listener
   // twice.
   if (mOnStopRequestCalled && mIPCActorDeleted) {
     return;
   }
 
   if (mDivertingToParent) {
     MOZ_RELEASE_ASSERT(
         !mFlushedForDiversion,
         "Should not be processing any more callbacks from parent!");
 
-    SendDivertOnStopRequest(aChannelStatus);
+    SendDivertOnStopRequest(channelStatus);
     return;
   }
 
   if (mUnknownDecoderInvolved) {
     LOG(("UnknownDecoder is involved queue OnStopRequest call. [this=%p]",
          this));
     MOZ_ASSERT(NS_IsMainThread());
-    RefPtr<HttpChannelChild> self = this;
     mUnknownDecoderEventQ.AppendElement(
-        MakeUnique<NeckoTargetChannelFunctionEvent>(
-            this, [=]() { self->MaybeDivertOnStop(aChannelStatus); }));
+        MakeUnique<MaybeDivertOnStopHttpEvent>(this, channelStatus));
   }
 
   nsCOMPtr<nsICompressConvStats> conv = do_QueryInterface(mCompressListener);
   if (conv) {
     conv->GetDecodedDataLength(&mDecodedBodySize);
   }
 
-  mTransactionTimings.domainLookupStart = aTiming.domainLookupStart;
-  mTransactionTimings.domainLookupEnd = aTiming.domainLookupEnd;
-  mTransactionTimings.connectStart = aTiming.connectStart;
-  mTransactionTimings.tcpConnectEnd = aTiming.tcpConnectEnd;
-  mTransactionTimings.secureConnectionStart = aTiming.secureConnectionStart;
-  mTransactionTimings.connectEnd = aTiming.connectEnd;
-  mTransactionTimings.requestStart = aTiming.requestStart;
-  mTransactionTimings.responseStart = aTiming.responseStart;
-  mTransactionTimings.responseEnd = aTiming.responseEnd;
+  mTransactionTimings.domainLookupStart = timing.domainLookupStart;
+  mTransactionTimings.domainLookupEnd = timing.domainLookupEnd;
+  mTransactionTimings.connectStart = timing.connectStart;
+  mTransactionTimings.tcpConnectEnd = timing.tcpConnectEnd;
+  mTransactionTimings.secureConnectionStart = timing.secureConnectionStart;
+  mTransactionTimings.connectEnd = timing.connectEnd;
+  mTransactionTimings.requestStart = timing.requestStart;
+  mTransactionTimings.responseStart = timing.responseStart;
+  mTransactionTimings.responseEnd = timing.responseEnd;
 
   // Do not overwrite or adjust the original mAsyncOpenTime by timing.fetchStart
   // We must use the original child process time in order to account for child
   // side work and IPC transit overhead.
   // XXX: This depends on TimeStamp being equivalent across processes.
   // This is true for modern hardware but for older platforms it is not always
   // true.
 
-  mRedirectStartTimeStamp = aTiming.redirectStart;
-  mRedirectEndTimeStamp = aTiming.redirectEnd;
-  mTransferSize = aTiming.transferSize;
-  mEncodedBodySize = aTiming.encodedBodySize;
-  mProtocolVersion = aTiming.protocolVersion;
-
-  mCacheReadStart = aTiming.cacheReadStart;
-  mCacheReadEnd = aTiming.cacheReadEnd;
+  mRedirectStartTimeStamp = timing.redirectStart;
+  mRedirectEndTimeStamp = timing.redirectEnd;
+  mTransferSize = timing.transferSize;
+  mEncodedBodySize = timing.encodedBodySize;
+  mProtocolVersion = timing.protocolVersion;
+
+  mCacheReadStart = timing.cacheReadStart;
+  mCacheReadEnd = timing.cacheReadEnd;
 
 #ifdef MOZ_GECKO_PROFILER
   if (profiler_can_accept_markers()) {
     int32_t priority = PRIORITY_NORMAL;
     GetPriority(&priority);
     profiler_add_network_marker(
         mURI, priority, mChannelId, NetworkLoadType::LOAD_STOP,
         mLastStatusReported, TimeStamp::Now(), mTransferSize, kCacheUnknown,
         &mTransactionTimings, nullptr, std::move(mSource));
   }
 #endif
 
   mResponseTrailers = new nsHttpHeaderArray(aResponseTrailers);
 
-  DoPreOnStopRequest(aChannelStatus);
+  DoPreOnStopRequest(channelStatus);
 
   {  // We must flush the queue before we Send__delete__
     // (although we really shouldn't receive any msgs after OnStop),
     // so make sure this goes out of scope before then.
     AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
-    DoOnStopRequest(this, aChannelStatus, nullptr);
+    DoOnStopRequest(this, channelStatus, nullptr);
     // DoOnStopRequest() calls ReleaseListeners()
   }
 
   // If unknownDecoder is involved and the received content is short we will
   // know whether we need to divert to parent only after OnStopRequest of the
   // listeners chain is called in DoOnStopRequest. At that moment
   // unknownDecoder will call OnStartRequest of the real listeners of the
   // channel including the OnStopRequest of UrlLoader which decides whether we
@@ -982,17 +1142,17 @@ void HttpChannelChild::OnStopRequest(
 
   CleanupBackgroundChannel();
 
   // If there is a possibility we might want to write alt data to the cache
   // entry, we keep the channel alive. We still send the DocumentChannelCleanup
   // message but request the cache entry to be kept by the parent.
   // If the channel has failed, the cache entry is in a non-writtable state and
   // we want to release it to not block following consumers.
-  if (NS_SUCCEEDED(aChannelStatus) && !mPreferredCachedAltDataTypes.IsEmpty()) {
+  if (NS_SUCCEEDED(channelStatus) && !mPreferredCachedAltDataTypes.IsEmpty()) {
     mKeptAlive = true;
     SendDocumentChannelCleanup(false);  // don't clear cache entry
     return;
   }
 
   if (mLoadFlags & LOAD_DOCUMENT_URI) {
     // Keep IPDL channel open, but only for updating security info.
     // If IPDL is already closed, then do nothing.
@@ -1100,44 +1260,76 @@ void HttpChannelChild::DoOnStopRequest(n
   if (!mPreferredCachedAltDataTypes.IsEmpty()) {
     mAltDataCacheEntryAvailable = mCacheEntryAvailable;
   }
   mCacheEntryAvailable = false;
 
   if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 }
 
+class ProgressEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  ProgressEvent(HttpChannelChild* child, const int64_t& progress,
+                const int64_t& progressMax)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child),
+        mProgress(progress),
+        mProgressMax(progressMax) {}
+
+  void Run() override {
+    AutoEventEnqueuer ensureSerialDispatch(mChild->mEventQ);
+    mChild->DoOnProgress(mChild, mProgress, mProgressMax);
+  }
+
+ private:
+  int64_t mProgress, mProgressMax;
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvOnProgress(
     const int64_t& aProgress, const int64_t& aProgressMax) {
   LOG(("HttpChannelChild::RecvOnProgress [this=%p]\n", this));
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=]() {
-    AutoEventEnqueuer ensureSerialDispatch(mEventQ);
-    self->DoOnProgress(self, aProgress, aProgressMax);
-  }));
+  mEventQ->RunOrEnqueue(new ProgressEvent(this, aProgress, aProgressMax));
   return IPC_OK();
 }
 
+class StatusEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  StatusEvent(HttpChannelChild* child, const nsresult& status)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child), mStatus(status) {}
+
+  void Run() override {
+    AutoEventEnqueuer ensureSerialDispatch(mChild->mEventQ);
+    mChild->DoOnStatus(mChild, mStatus);
+  }
+
+ private:
+  nsresult mStatus;
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvOnStatus(
     const nsresult& aStatus) {
   LOG(("HttpChannelChild::RecvOnStatus [this=%p]\n", this));
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=]() {
-    AutoEventEnqueuer ensureSerialDispatch(self->mEventQ);
-    self->DoOnStatus(self, aStatus);
-  }));
+  mEventQ->RunOrEnqueue(new StatusEvent(this, aStatus));
   return IPC_OK();
 }
 
+class FailedAsyncOpenEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  FailedAsyncOpenEvent(HttpChannelChild* child, const nsresult& status)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child), mStatus(status) {}
+
+  void Run() override { mChild->FailedAsyncOpen(mStatus); }
+
+ private:
+  nsresult mStatus;
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvFailedAsyncOpen(
-    const nsresult& aStatus) {
+    const nsresult& status) {
   LOG(("HttpChannelChild::RecvFailedAsyncOpen [this=%p]\n", this));
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=]() { self->FailedAsyncOpen(aStatus); }));
+  mEventQ->RunOrEnqueue(new FailedAsyncOpenEvent(this, status));
   return IPC_OK();
 }
 
 // We need to have an implementation of this function just so that we can keep
 // all references to mCallOnResume of type HttpChannelChild:  it's not OK in C++
 // to set a member function ptr to a base class function.
 void HttpChannelChild::HandleAsyncAbort() {
   HttpAsyncAborter<HttpChannelChild>::HandleAsyncAbort();
@@ -1207,21 +1399,26 @@ void HttpChannelChild::DoNotifyListenerC
 
   MaybeCallSynthesizedCallback();
 }
 
 void HttpChannelChild::DoAsyncAbort(nsresult aStatus) {
   Unused << AsyncAbort(aStatus);
 }
 
+class DeleteSelfEvent : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  explicit DeleteSelfEvent(HttpChannelChild* child)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child) {}
+  void Run() override { mChild->DeleteSelf(); }
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvDeleteSelf() {
   LOG(("HttpChannelChild::RecvDeleteSelf [this=%p]\n", this));
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(
-      new NeckoTargetChannelFunctionEvent(this, [=]() { self->DeleteSelf(); }));
+  mEventQ->RunOrEnqueue(new DeleteSelfEvent(this));
   return IPC_OK();
 }
 
 HttpChannelChild::OverrideRunnable::OverrideRunnable(
     HttpChannelChild* aChannel, HttpChannelChild* aNewChannel,
     InterceptStreamListener* aListener, nsIInputStream* aInput,
     nsIInterceptedBodyCallback* aCallback, nsAutoPtr<nsHttpResponseHead>& aHead,
     nsICacheInfoChannel* aCacheInfo)
@@ -1295,16 +1492,24 @@ mozilla::ipc::IPCResult HttpChannelChild
                         this, &HttpChannelChild::FinishInterceptedRedirect),
       NS_DISPATCH_NORMAL);
 
   return IPC_OK();
 }
 
 void HttpChannelChild::DeleteSelf() { Send__delete__(this); }
 
+class ContinueDoNotifyListenerEvent
+    : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  explicit ContinueDoNotifyListenerEvent(HttpChannelChild* child)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child) {}
+  void Run() override { mChild->ContinueDoNotifyListener(); }
+};
+
 void HttpChannelChild::DoNotifyListener() {
   LOG(("HttpChannelChild::DoNotifyListener this=%p", this));
   MOZ_ASSERT(NS_IsMainThread());
 
   // In case nsHttpChannel::OnStartRequest wasn't called (e.g. due to flag
   // LOAD_ONLY_IF_MODIFIED) we want to set mAfterOnStartRequestBegun to true
   // before notifying listener.
   if (!mAfterOnStartRequestBegun) {
@@ -1313,19 +1518,17 @@ void HttpChannelChild::DoNotifyListener(
 
   if (mListener && !mOnStartRequestCalled) {
     nsCOMPtr<nsIStreamListener> listener = mListener;
     mOnStartRequestCalled = true;  // avoid reentrancy bugs by setting this now
     listener->OnStartRequest(this);
   }
   mOnStartRequestCalled = true;
 
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=] { self->ContinueDoNotifyListener(); }));
+  mEventQ->RunOrEnqueue(new ContinueDoNotifyListenerEvent(this));
 }
 
 void HttpChannelChild::ContinueDoNotifyListener() {
   LOG(("HttpChannelChild::ContinueDoNotifyListener this=%p", this));
   MOZ_ASSERT(NS_IsMainThread());
 
   // Make sure mIsPending is set to false. At this moment we are done from
   // the point of view of our consumer and we have to report our self
@@ -1389,38 +1592,73 @@ void HttpChannelChild::FinishIntercepted
 
 mozilla::ipc::IPCResult HttpChannelChild::RecvReportSecurityMessage(
     const nsString& messageTag, const nsString& messageCategory) {
   DebugOnly<nsresult> rv = AddSecurityMessage(messageTag, messageCategory);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
   return IPC_OK();
 }
 
+class Redirect1Event : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  Redirect1Event(HttpChannelChild* child, const uint32_t& registrarId,
+                 const URIParams& newURI, const uint32_t& newLoadFlags,
+                 const uint32_t& redirectFlags,
+                 const ParentLoadInfoForwarderArgs& loadInfoForwarder,
+                 const nsHttpResponseHead& responseHead,
+                 const nsACString& securityInfoSerialization,
+                 const uint64_t& channelId, const ResourceTimingStruct& timing)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child),
+        mRegistrarId(registrarId),
+        mNewURI(newURI),
+        mNewLoadFlags(newLoadFlags),
+        mRedirectFlags(redirectFlags),
+        mResponseHead(responseHead),
+        mSecurityInfoSerialization(securityInfoSerialization),
+        mChannelId(channelId),
+        mLoadInfoForwarder(loadInfoForwarder),
+        mTiming(timing) {}
+
+  void Run() override {
+    mChild->Redirect1Begin(mRegistrarId, mNewURI, mNewLoadFlags, mRedirectFlags,
+                           mLoadInfoForwarder, mResponseHead,
+                           mSecurityInfoSerialization, mChannelId, mTiming);
+  }
+
+ private:
+  uint32_t mRegistrarId;
+  URIParams mNewURI;
+  uint32_t mNewLoadFlags;
+  uint32_t mRedirectFlags;
+  nsHttpResponseHead mResponseHead;
+  nsCString mSecurityInfoSerialization;
+  uint64_t mChannelId;
+  ParentLoadInfoForwarderArgs mLoadInfoForwarder;
+  ResourceTimingStruct mTiming;
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvRedirect1Begin(
-    const uint32_t& aRegistrarId, const URIParams& aNewUri,
-    const uint32_t& aNewLoadFlags, const uint32_t& aRedirectFlags,
-    const ParentLoadInfoForwarderArgs& aLoadInfoForwarder,
-    const nsHttpResponseHead& aResponseHead,
-    const nsCString& aSecurityInfoSerialization, const uint64_t& aChannelId,
-    const NetAddr& aOldPeerAddr, const ResourceTimingStruct& aTiming) {
+    const uint32_t& registrarId, const URIParams& newUri,
+    const uint32_t& newLoadFlags, const uint32_t& redirectFlags,
+    const ParentLoadInfoForwarderArgs& loadInfoForwarder,
+    const nsHttpResponseHead& responseHead,
+    const nsCString& securityInfoSerialization, const uint64_t& channelId,
+    const NetAddr& oldPeerAddr, const ResourceTimingStruct& timing) {
   // TODO: handle security info
   LOG(("HttpChannelChild::RecvRedirect1Begin [this=%p]\n", this));
   // We set peer address of child to the old peer,
   // Then it will be updated to new peer in OnStartRequest
-  mPeerAddr = aOldPeerAddr;
+  mPeerAddr = oldPeerAddr;
 
   // Cookies headers should not be visible to the child process
-  MOZ_ASSERT(!nsHttpResponseHead(aResponseHead).HasHeader(nsHttp::Set_Cookie));
-
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=]() {
-    self->Redirect1Begin(aRegistrarId, aNewUri, aNewLoadFlags, aRedirectFlags,
-                         aLoadInfoForwarder, aResponseHead,
-                         aSecurityInfoSerialization, aChannelId, aTiming);
-  }));
+  MOZ_ASSERT(!nsHttpResponseHead(responseHead).HasHeader(nsHttp::Set_Cookie));
+
+  mEventQ->RunOrEnqueue(new Redirect1Event(
+      this, registrarId, newUri, newLoadFlags, redirectFlags, loadInfoForwarder,
+      responseHead, securityInfoSerialization, channelId, timing));
   return IPC_OK();
 }
 
 nsresult HttpChannelChild::SetupRedirect(nsIURI* uri,
                                          const nsHttpResponseHead* responseHead,
                                          const uint32_t& redirectFlags,
                                          nsIChannel** outChannel) {
   LOG(("HttpChannelChild::SetupRedirect [this=%p]\n", this));
@@ -1595,107 +1833,119 @@ void HttpChannelChild::BeginNonIPCRedire
 
 void HttpChannelChild::OverrideSecurityInfoForNonIPCRedirect(
     nsISupports* securityInfo) {
   mResponseCouldBeSynthesized = true;
   DebugOnly<nsresult> rv = OverrideSecurityInfo(securityInfo);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
 }
 
+class Redirect3Event : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  explicit Redirect3Event(HttpChannelChild* child)
+      : NeckoTargetChannelEvent<HttpChannelChild>(child) {}
+  void Run() override { mChild->Redirect3Complete(nullptr); }
+};
+
 mozilla::ipc::IPCResult HttpChannelChild::RecvRedirect3Complete() {
   LOG(("HttpChannelChild::RecvRedirect3Complete [this=%p]\n", this));
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [self]() { self->Redirect3Complete(nullptr); }));
+  mEventQ->RunOrEnqueue(new Redirect3Event(this));
   return IPC_OK();
 }
 
+class HttpFlushedForDiversionEvent
+    : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  explicit HttpFlushedForDiversionEvent(HttpChannelChild* aChild)
+      : NeckoTargetChannelEvent<HttpChannelChild>(aChild) {
+    MOZ_RELEASE_ASSERT(aChild);
+  }
+
+  void Run() override { mChild->FlushedForDiversion(); }
+};
+
 void HttpChannelChild::ProcessFlushedForDiversion() {
   LOG(("HttpChannelChild::ProcessFlushedForDiversion [this=%p]\n", this));
   MOZ_ASSERT(OnSocketThread());
   MOZ_RELEASE_ASSERT(mDivertingToParent);
 
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-                            this, [self]() { self->FlushedForDiversion(); }),
-                        true);
+  mEventQ->RunOrEnqueue(new HttpFlushedForDiversionEvent(this), true);
 }
 
-mozilla::ipc::IPCResult
-HttpChannelChild::RecvNotifyChannelClassifierProtectionDisabled(
-    const uint32_t& aAcceptedReason) {
+void HttpChannelChild::ProcessNotifyChannelClassifierProtectionDisabled(
+    uint32_t aAcceptedReason) {
   LOG(
-      ("HttpChannelChild::RecvNotifyChannelClassifierProtectionDisabled "
+      ("HttpChannelChild::ProcessNotifyChannelClassifierProtectionDisabled "
        "[this=%p aAcceptedReason=%" PRIu32 "]\n",
        this, aAcceptedReason));
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(OnSocketThread());
 
   RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=] {
-    UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
-        self, aAcceptedReason);
-  }));
-
-  return IPC_OK();
+  nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
+  neckoTarget->Dispatch(
+      NS_NewRunnableFunction(
+          "AntiTrackingCommon::NotifyChannelClassifierProtectionDisabled",
+          [self, aAcceptedReason]() {
+            UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
+                self, aAcceptedReason);
+          }),
+      NS_DISPATCH_NORMAL);
 }
 
-mozilla::ipc::IPCResult HttpChannelChild::RecvNotifyCookieAllowed() {
-  LOG(("HttpChannelChild::RecvNotifyCookieAllowed [this=%p]\n", this));
-  MOZ_ASSERT(NS_IsMainThread());
+void HttpChannelChild::ProcessNotifyCookieAllowed() {
+  LOG(("HttpChannelChild::ProcessNotifyCookieAllowed [this=%p]\n", this));
+  MOZ_ASSERT(OnSocketThread());
 
   RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=] {
-    AntiTrackingCommon::NotifyBlockingDecision(
-        self, AntiTrackingCommon::BlockingDecision::eAllow, 0);
-  }));
-
-  return IPC_OK();
+  nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
+  neckoTarget->Dispatch(
+      NS_NewRunnableFunction(
+          "UrlClassifierCommon::NotifyBlockingDecision",
+          [self]() {
+            AntiTrackingCommon::NotifyBlockingDecision(
+                self, AntiTrackingCommon::BlockingDecision::eAllow, 0);
+          }),
+      NS_DISPATCH_NORMAL);
 }
 
-mozilla::ipc::IPCResult HttpChannelChild::RecvNotifyCookieBlocked(
-    const uint32_t& aRejectedReason) {
-  LOG(("HttpChannelChild::RecvNotifyCookieBlocked [this=%p]\n", this));
-  MOZ_ASSERT(NS_IsMainThread());
+void HttpChannelChild::ProcessNotifyCookieBlocked(uint32_t aRejectedReason) {
+  LOG(("HttpChannelChild::ProcessNotifyCookieBlocked [this=%p]\n", this));
+  MOZ_ASSERT(OnSocketThread());
 
   RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=] {
-    AntiTrackingCommon::NotifyBlockingDecision(
-        self, AntiTrackingCommon::BlockingDecision::eBlock, aRejectedReason);
-  }));
-
-  return IPC_OK();
+  nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
+  neckoTarget->Dispatch(
+      NS_NewRunnableFunction("AntiTrackingCommon::NotifyBlockingDecision",
+                             [self, aRejectedReason]() {
+                               AntiTrackingCommon::NotifyBlockingDecision(
+                                   self,
+                                   AntiTrackingCommon::BlockingDecision::eBlock,
+                                   aRejectedReason);
+                             }),
+      NS_DISPATCH_NORMAL);
 }
 
-mozilla::ipc::IPCResult HttpChannelChild::RecvNotifyClassificationFlags(
-    const uint32_t& aClassificationFlags, const bool& aIsThirdParty) {
+void HttpChannelChild::ProcessNotifyClassificationFlags(
+    uint32_t aClassificationFlags, bool aIsThirdParty) {
   LOG(
-      ("HttpChannelChild::RecvNotifyClassificationFlags thirdparty=%d "
+      ("HttpChannelChild::ProcessNotifyClassificationFlags thirdparty=%d "
        "flags=%" PRIu32 " [this=%p]\n",
        static_cast<int>(aIsThirdParty), aClassificationFlags, this));
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=] {
-    self->AddClassificationFlags(aClassificationFlags, aIsThirdParty);
-  }));
-
-  return IPC_OK();
+  MOZ_ASSERT(OnSocketThread());
+
+  AddClassificationFlags(aClassificationFlags, aIsThirdParty);
 }
 
-mozilla::ipc::IPCResult HttpChannelChild::RecvNotifyFlashPluginStateChanged(
-    const nsIHttpChannel::FlashPluginState& aState) {
-  LOG(("HttpChannelChild::RecvNotifyFlashPluginStateChanged [this=%p]\n",
+void HttpChannelChild::ProcessNotifyFlashPluginStateChanged(
+    nsIHttpChannel::FlashPluginState aState) {
+  LOG(("HttpChannelChild::ProcessNotifyFlashPluginStateChanged [this=%p]\n",
        this));
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=] { self->SetFlashPluginState(aState); }));
-
-  return IPC_OK();
+  MOZ_ASSERT(OnSocketThread());
+
+  SetFlashPluginState(aState);
 }
 
 void HttpChannelChild::FlushedForDiversion() {
   LOG(("HttpChannelChild::FlushedForDiversion [this=%p]\n", this));
   MOZ_RELEASE_ASSERT(mDivertingToParent);
 
   // Once this is set, it should not be unset before HttpChannelChild is taken
   // down. After it is set, no OnStart/OnData/OnStop callbacks should be
@@ -1704,48 +1954,50 @@ void HttpChannelChild::FlushedForDiversi
 
   // If we're synthesized, it's up to the SyntheticDiversionListener to invoke
   // SendDivertComplete after it has sent the DivertOnStopRequestMessage.
   if (!mSynthesizedResponse) {
     SendDivertComplete();
   }
 }
 
-mozilla::ipc::IPCResult HttpChannelChild::RecvSetClassifierMatchedInfo(
-    const ClassifierInfo& aInfo) {
-  LOG(("HttpChannelChild::RecvSetClassifierMatchedInfo [this=%p]\n", this));
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(this, [=]() {
-    self->SetMatchedInfo(aInfo.list(), aInfo.provider(), aInfo.fullhash());
-  }));
-
-  return IPC_OK();
+void HttpChannelChild::ProcessSetClassifierMatchedInfo(
+    const nsCString& aList, const nsCString& aProvider,
+    const nsCString& aFullHash) {
+  LOG(("HttpChannelChild::ProcessSetClassifierMatchedInfo [this=%p]\n", this));
+  MOZ_ASSERT(OnSocketThread());
+
+  nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
+  neckoTarget->Dispatch(
+      NewRunnableMethod<const nsCString, const nsCString, const nsCString>(
+          "HttpChannelChild::SetMatchedInfo", this,
+          &HttpChannelChild::SetMatchedInfo, aList, aProvider, aFullHash),
+      NS_DISPATCH_NORMAL);
 }
 
-mozilla::ipc::IPCResult HttpChannelChild::RecvSetClassifierMatchedTrackingInfo(
-    const ClassifierInfo& aInfo) {
-  LOG(("HttpChannelChild::RecvSetClassifierMatchedTrackingInfo [this=%p]\n",
+void HttpChannelChild::ProcessSetClassifierMatchedTrackingInfo(
+    const nsCString& aLists, const nsCString& aFullHashes) {
+  LOG(("HttpChannelChild::ProcessSetClassifierMatchedTrackingInfo [this=%p]\n",
        this));
-  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(OnSocketThread());
 
   nsTArray<nsCString> lists, fullhashes;
-  for (const nsACString& token : aInfo.list().Split(',')) {
+  for (const nsACString& token : aLists.Split(',')) {
     lists.AppendElement(token);
   }
-  for (const nsACString& token : aInfo.fullhash().Split(',')) {
+  for (const nsACString& token : aFullHashes.Split(',')) {
     fullhashes.AppendElement(token);
   }
 
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
-      this, [=]() { self->SetMatchedTrackingInfo(lists, fullhashes); }));
-
-  return IPC_OK();
+  nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
+  neckoTarget->Dispatch(
+      NewRunnableMethod<const nsTArray<nsCString>, const nsTArray<nsCString>>(
+          "HttpChannelChild::SetMatchedTrackingInfo", this,
+          &HttpChannelChild::SetMatchedTrackingInfo, lists, fullhashes),
+      NS_DISPATCH_NORMAL);
 }
 
 void HttpChannelChild::ProcessDivertMessages() {
   LOG(("HttpChannelChild::ProcessDivertMessages [this=%p]\n", this));
   MOZ_ASSERT(OnSocketThread());
   MOZ_RELEASE_ASSERT(mDivertingToParent);
 
   // DivertTo() has been called on parent, so we can now start sending queued
@@ -1904,17 +2156,17 @@ HttpChannelChild::ConnectParent(uint32_t
 
     mBgChild = bgChild.forget();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-HttpChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener,
+HttpChannelChild::CompleteRedirectSetup(nsIStreamListener* listener,
                                         nsISupports* aContext) {
   LOG(("HttpChannelChild::FinishRedirectSetup [this=%p]\n", this));
   MOZ_ASSERT(NS_IsMainThread());
 
   NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
   NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
 
   if (mShouldParentIntercept) {
@@ -1926,17 +2178,17 @@ HttpChannelChild::CompleteRedirectSetup(
     // Since this method is called from RecvRedirect3Complete which itself is
     // called from either OnRedirectVerifyCallback via OverrideRunnable, or from
     // RecvRedirect3Complete. The order of events must always be:
     //  1. Teardown the IPDL connection
     //  2. AsyncOpen the connection again
     //  3. Cleanup the redirecting channel (the one calling Redirect3Complete)
     //  4. [optional] Call OverrideWithSynthesizedResponse on the redirected
     //  channel if the call came from OverrideRunnable.
-    mInterceptedRedirectListener = aListener;
+    mInterceptedRedirectListener = listener;
     mInterceptedRedirectContext = aContext;
 
     // This will send a message to the parent notifying it that we are closing
     // down. After closing the IPC channel, we will proceed to execute
     // FinishInterceptedRedirect() which AsyncOpen's the channel again.
     SendFinishInterceptedRedirect();
 
     // XXX valentin: The interception logic should be rewritten to avoid
@@ -1953,50 +2205,50 @@ HttpChannelChild::CompleteRedirectSetup(
 
   mLastStatusReported = TimeStamp::Now();
   PROFILER_ADD_NETWORK_MARKER(mURI, mPriority, mChannelId,
                               NetworkLoadType::LOAD_START,
                               mChannelCreationTimestamp, mLastStatusReported, 0,
                               kCacheUnknown, nullptr, nullptr);
   mIsPending = true;
   mWasOpened = true;
-  mListener = aListener;
+  mListener = listener;
 
   // add ourselves to the load group.
   if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr);
 
   // We already have an open IPDL connection to the parent. If on-modify-request
   // listeners or load group observers canceled us, let the parent handle it
   // and send it back to us naturally.
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelChild::nsIAsyncVerifyRedirectCallback
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-HttpChannelChild::OnRedirectVerifyCallback(nsresult aResult) {
+HttpChannelChild::OnRedirectVerifyCallback(nsresult result) {
   LOG(("HttpChannelChild::OnRedirectVerifyCallback [this=%p]\n", this));
   MOZ_ASSERT(NS_IsMainThread());
   Maybe<URIParams> redirectURI;
   nsresult rv;
 
   nsCOMPtr<nsIHttpChannel> newHttpChannel =
       do_QueryInterface(mRedirectChannelChild);
 
-  if (NS_SUCCEEDED(aResult) && !mRedirectChannelChild) {
+  if (NS_SUCCEEDED(result) && !mRedirectChannelChild) {
     // mRedirectChannelChild doesn't exist means we're redirecting to a protocol
     // that doesn't implement nsIChildChannel. The redirect result should be set
     // as failed by veto listeners and shouldn't enter this condition. As the
     // last resort, we synthesize the error result as NS_ERROR_DOM_BAD_URI here
     // to let nsHttpChannel::ContinueProcessResponse2 know it's redirecting to
     // another protocol and throw an error.
     LOG(("  redirecting to a protocol that doesn't implement nsIChildChannel"));
-    aResult = NS_ERROR_DOM_BAD_URI;
+    result = NS_ERROR_DOM_BAD_URI;
   }
 
   nsCOMPtr<nsIReferrerInfo> referrerInfo;
   if (newHttpChannel) {
     // Must not be called until after redirect observers called.
     newHttpChannel->SetOriginalURI(mOriginalURI);
     referrerInfo = newHttpChannel->GetReferrerInfo();
   }
@@ -2029,29 +2281,29 @@ HttpChannelChild::OnRedirectVerifyCallba
 
   RequestHeaderTuples emptyHeaders;
   RequestHeaderTuples* headerTuples = &emptyHeaders;
   nsLoadFlags loadFlags = 0;
   Maybe<CorsPreflightArgs> corsPreflightArgs;
 
   nsCOMPtr<nsIHttpChannelChild> newHttpChannelChild =
       do_QueryInterface(mRedirectChannelChild);
-  if (newHttpChannelChild && NS_SUCCEEDED(aResult)) {
+  if (newHttpChannelChild && NS_SUCCEEDED(result)) {
     rv = newHttpChannelChild->AddCookiesToRequest();
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     rv = newHttpChannelChild->GetClientSetRequestHeaders(&headerTuples);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     newHttpChannelChild->GetClientSetCorsPreflightParameters(corsPreflightArgs);
   }
 
   /* If the redirect was canceled, bypass OMR and send an empty API
    * redirect URI */
   SerializeURI(nullptr, redirectURI);
 
-  if (NS_SUCCEEDED(aResult)) {
+  if (NS_SUCCEEDED(result)) {
     // Note: this is where we would notify "http-on-modify-response" observers.
     // We have deliberately disabled this for child processes (see bug 806753)
     //
     // After we verify redirect, nsHttpChannel may hit the network: must give
     // "http-on-modify-request" observers the chance to cancel before that.
     // base->CallOnModifyRequestObservers();
 
     nsCOMPtr<nsIHttpChannelInternal> newHttpChannelInternal =
@@ -2093,56 +2345,56 @@ HttpChannelChild::OnRedirectVerifyCallba
     newChannelLoadInfo = newChannel->LoadInfo();
   }
 
   ChildLoadInfoForwarderArgs targetLoadInfoForwarder;
   LoadInfoToChildLoadInfoForwarder(newChannelLoadInfo,
                                    &targetLoadInfoForwarder);
 
   if (CanSend())
-    SendRedirect2Verify(aResult, *headerTuples, sourceRequestBlockingReason,
+    SendRedirect2Verify(result, *headerTuples, sourceRequestBlockingReason,
                         targetLoadInfoForwarder, loadFlags, referrerInfo,
                         redirectURI, corsPreflightArgs, chooseAppcache);
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelChild::nsIRequest
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
-HttpChannelChild::Cancel(nsresult aStatus) {
+HttpChannelChild::Cancel(nsresult status) {
   LOG(("HttpChannelChild::Cancel [this=%p, status=%" PRIx32 "]\n", this,
-       static_cast<uint32_t>(aStatus)));
+       static_cast<uint32_t>(status)));
   LogCallingScriptLocation(this);
 
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!mCanceled) {
     // If this cancel occurs before nsHttpChannel has been set up, AsyncOpen
     // is responsible for cleaning up.
     mCanceled = true;
-    mStatus = aStatus;
+    mStatus = status;
     if (RemoteChannelExists()) {
-      SendCancel(aStatus);
+      SendCancel(status);
     }
 
     // If the channel is intercepted and already pumping, then just
     // cancel the pump.  This will call OnStopRequest().
     if (mSynthesizedResponsePump) {
-      mSynthesizedResponsePump->Cancel(aStatus);
+      mSynthesizedResponsePump->Cancel(status);
     }
 
     // If we are canceled while intercepting, but not yet pumping, then
     // we must call AsyncAbort() to trigger OnStopRequest().
     else if (mInterceptListener) {
       mInterceptListener->Cleanup();
       mInterceptListener = nullptr;
-      Unused << AsyncAbort(aStatus);
+      Unused << AsyncAbort(status);
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelChild::Suspend() {
   LOG(("HttpChannelChild::Suspend [this=%p, mSuspendCount=%" PRIu32 ", "
@@ -3491,31 +3743,47 @@ nsresult HttpChannelChild::SetReferrerHe
             mClientSetRequestHeaders[i].mHeader)) {
       mClientSetRequestHeaders.RemoveElementAt(i);
     }
   }
 
   return HttpBaseChannel::SetReferrerHeader(aReferrer, aRespectBeforeConnect);
 }
 
+class CancelEvent final : public NeckoTargetChannelEvent<HttpChannelChild> {
+ public:
+  CancelEvent(HttpChannelChild* aChild, nsresult aRv)
+      : NeckoTargetChannelEvent<HttpChannelChild>(aChild), mRv(aRv) {
+    MOZ_ASSERT(!NS_IsMainThread());
+    MOZ_ASSERT(aChild);
+  }
+
+  void Run() override {
+    MOZ_ASSERT(NS_IsMainThread());
+    mChild->Cancel(mRv);
+  }
+
+ private:
+  const nsresult mRv;
+};
+
 void HttpChannelChild::CancelOnMainThread(nsresult aRv) {
   LOG(("HttpChannelChild::CancelOnMainThread [this=%p]", this));
 
   if (NS_IsMainThread()) {
     Cancel(aRv);
     return;
   }
 
   mEventQ->Suspend();
   // Cancel is expected to preempt any other channel events, thus we put this
   // event in the front of mEventQ to make sure nsIStreamListener not receiving
   // any ODA/OnStopRequest callbacks.
-  RefPtr<HttpChannelChild> self = this;
-  mEventQ->PrependEvent(MakeUnique<NeckoTargetChannelFunctionEvent>(
-      this, [self, aRv]() { self->Cancel(aRv); }));
+  UniquePtr<ChannelEvent> cancelEvent = MakeUnique<CancelEvent>(this, aRv);
+  mEventQ->PrependEvent(cancelEvent);
   mEventQ->Resume();
 }
 
 void HttpChannelChild::OverrideWithSynthesizedResponse(
     nsAutoPtr<nsHttpResponseHead>& aResponseHead,
     nsIInputStream* aSynthesizedInput,
     nsIInterceptedBodyCallback* aSynthesizedCallback,
     InterceptStreamListener* aStreamListener,
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -177,36 +177,16 @@ class HttpChannelChild final : public PH
       const Maybe<IPCStream>& aStream) override;
 
   mozilla::ipc::IPCResult RecvAltDataCacheInputStreamAvailable(
       const Maybe<IPCStream>& aStream) override;
 
   mozilla::ipc::IPCResult RecvOverrideReferrerInfoDuringBeginConnect(
       nsIReferrerInfo* aReferrerInfo) override;
 
-  mozilla::ipc::IPCResult RecvNotifyChannelClassifierProtectionDisabled(
-      const uint32_t& aAcceptedReason) override;
-
-  mozilla::ipc::IPCResult RecvNotifyCookieAllowed() override;
-
-  mozilla::ipc::IPCResult RecvNotifyCookieBlocked(
-      const uint32_t& aRejectedReason) override;
-
-  mozilla::ipc::IPCResult RecvNotifyClassificationFlags(
-      const uint32_t& aClassificationFlags, const bool& aIsThirdParty) override;
-
-  mozilla::ipc::IPCResult RecvNotifyFlashPluginStateChanged(
-      const nsIHttpChannel::FlashPluginState& aState) override;
-
-  mozilla::ipc::IPCResult RecvSetClassifierMatchedInfo(
-      const ClassifierInfo& info) override;
-
-  mozilla::ipc::IPCResult RecvSetClassifierMatchedTrackingInfo(
-      const ClassifierInfo& info) override;
-
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual void DoNotifyListenerCleanup() override;
 
   virtual void DoAsyncAbort(nsresult aStatus) override;
 
   nsresult AsyncCall(
       void (HttpChannelChild::*funcPtr)(),
@@ -285,16 +265,29 @@ class HttpChannelChild final : public PH
                                  const uint64_t& aOffset,
                                  const uint32_t& aCount,
                                  const nsCString& aData);
   void ProcessOnStopRequest(const nsresult& aStatusCode,
                             const ResourceTimingStruct& aTiming,
                             const nsHttpHeaderArray& aResponseTrailers);
   void ProcessFlushedForDiversion();
   void ProcessDivertMessages();
+  void ProcessNotifyChannelClassifierProtectionDisabled(
+      uint32_t aAcceptedReason);
+  void ProcessNotifyCookieAllowed();
+  void ProcessNotifyCookieBlocked(uint32_t aRejectedReason);
+  void ProcessNotifyClassificationFlags(uint32_t aClassificationFlags,
+                                        bool aIsThirdParty);
+  void ProcessNotifyFlashPluginStateChanged(
+      nsIHttpChannel::FlashPluginState aState);
+  void ProcessSetClassifierMatchedInfo(const nsCString& aList,
+                                       const nsCString& aProvider,
+                                       const nsCString& aFullHash);
+  void ProcessSetClassifierMatchedTrackingInfo(const nsCString& aLists,
+                                               const nsCString& aFullHashes);
 
   // Return true if we need to tell the parent the size of unreported received
   // data
   bool NeedToReportBytesRead();
   int32_t mUnreportBytesRead = 0;
 
   void DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext);
   void DoOnStatus(nsIRequest* aRequest, nsresult status);
@@ -525,21 +518,36 @@ class HttpChannelChild final : public PH
                            bool responseRedirected);
 
   // Override the default security info pointer during a non-IPC redirection.
   void OverrideSecurityInfoForNonIPCRedirect(nsISupports* securityInfo);
 
   // Collect telemetry for the successful rate of OMT.
   void CollectOMTTelemetry();
 
+  friend class AssociateApplicationCacheEvent;
+  friend class StartRequestEvent;
+  friend class StopRequestEvent;
+  friend class TransportAndDataEvent;
+  friend class MaybeDivertOnDataHttpEvent;
+  friend class MaybeDivertOnStopHttpEvent;
+  friend class ProgressEvent;
+  friend class StatusEvent;
+  friend class FailedAsyncOpenEvent;
+  friend class Redirect1Event;
+  friend class Redirect3Event;
+  friend class DeleteSelfEvent;
+  friend class HttpFlushedForDiversionEvent;
+  friend class CancelEvent;
   friend class HttpAsyncAborter<HttpChannelChild>;
   friend class InterceptStreamListener;
   friend class InterceptedChannelContent;
   friend class HttpBackgroundChannelChild;
-  friend class NeckoTargetChannelFunctionEvent;
+  friend class NeckoTargetChannelEvent<HttpChannelChild>;
+  friend class ContinueDoNotifyListenerEvent;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelChild, HTTP_CHANNEL_CHILD_IID)
 
 // A stream listener interposed between the nsInputStreamPump used for
 // intercepted channels and this channel's original listener. This is only used
 // to ensure the original listener sees the channel as the request object, and
 // to synthesize OnStatus and OnProgress notifications.
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -1849,90 +1849,92 @@ HttpChannelParent::SetParentListener(Par
 NS_IMETHODIMP
 HttpChannelParent::NotifyChannelClassifierProtectionDisabled(
     uint32_t aAcceptedReason) {
   LOG(
       ("HttpChannelParent::NotifyChannelClassifierProtectionDisabled [this=%p "
        "aAcceptedReason=%" PRIu32 "]\n",
        this, aAcceptedReason));
   if (!mIPCClosed) {
-    Unused << SendNotifyChannelClassifierProtectionDisabled(aAcceptedReason);
+    MOZ_ASSERT(mBgParent);
+    Unused << NS_WARN_IF(
+        !mBgParent->OnNotifyChannelClassifierProtectionDisabled(
+            aAcceptedReason));
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::NotifyCookieAllowed() {
   LOG(("HttpChannelParent::NotifyCookieAllowed [this=%p]\n", this));
   if (!mIPCClosed) {
-    Unused << SendNotifyCookieAllowed();
+    MOZ_ASSERT(mBgParent);
+    Unused << NS_WARN_IF(!mBgParent->OnNotifyCookieAllowed());
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
   LOG(("HttpChannelParent::NotifyCookieBlocked [this=%p]\n", this));
   if (!mIPCClosed) {
-    Unused << SendNotifyCookieBlocked(aRejectedReason);
+    MOZ_ASSERT(mBgParent);
+    Unused << NS_WARN_IF(!mBgParent->OnNotifyCookieBlocked(aRejectedReason));
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
                                             const nsACString& aProvider,
                                             const nsACString& aFullHash) {
   LOG(("HttpChannelParent::SetClassifierMatchedInfo [this=%p]\n", this));
   if (!mIPCClosed) {
-    ClassifierInfo info;
-    info.list() = aList;
-    info.provider() = aProvider;
-    info.fullhash() = aFullHash;
-
-    Unused << SendSetClassifierMatchedInfo(info);
+    MOZ_ASSERT(mBgParent);
+    Unused << mBgParent->OnSetClassifierMatchedInfo(aList, aProvider,
+                                                    aFullHash);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::SetClassifierMatchedTrackingInfo(
     const nsACString& aLists, const nsACString& aFullHashes) {
   LOG(("HttpChannelParent::SetClassifierMatchedTrackingInfo [this=%p]\n",
        this));
   if (!mIPCClosed) {
-    ClassifierInfo info;
-    info.list() = aLists;
-    info.fullhash() = aFullHashes;
-
-    Unused << SendSetClassifierMatchedTrackingInfo(info);
+    MOZ_ASSERT(mBgParent);
+    Unused << mBgParent->OnSetClassifierMatchedTrackingInfo(aLists,
+                                                            aFullHashes);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
                                              bool aIsThirdParty) {
   LOG(
       ("HttpChannelParent::NotifyClassificationFlags "
        "classificationFlags=%" PRIu32 ", thirdparty=%d [this=%p]\n",
        aClassificationFlags, static_cast<int>(aIsThirdParty), this));
   if (!mIPCClosed) {
-    Unused << SendNotifyClassificationFlags(aClassificationFlags,
-                                            aIsThirdParty);
+    MOZ_ASSERT(mBgParent);
+    Unused << mBgParent->OnNotifyClassificationFlags(aClassificationFlags,
+                                                     aIsThirdParty);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::NotifyFlashPluginStateChanged(
     nsIHttpChannel::FlashPluginState aState) {
   LOG(("HttpChannelParent::NotifyFlashPluginStateChanged [this=%p]\n", this));
   if (!mIPCClosed) {
-    Unused << SendNotifyFlashPluginStateChanged(aState);
+    MOZ_ASSERT(mBgParent);
+    Unused << mBgParent->OnNotifyFlashPluginStateChanged(aState);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpChannelParent::Delete() {
   if (!mIPCClosed) Unused << DoSendDeleteSelf();
 
--- a/netwerk/protocol/http/PHttpBackgroundChannel.ipdl
+++ b/netwerk/protocol/http/PHttpBackgroundChannel.ipdl
@@ -2,21 +2,23 @@
 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 include protocol PBackground;
 include NeckoChannelParams;
+include PURLClassifierInfo;
 
 include "mozilla/net/NeckoMessageUtils.h";
 
 using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
 using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h";
+using nsIHttpChannel::FlashPluginState from "mozilla/net/NeckoMessageUtils.h";
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 async refcounted protocol PHttpBackgroundChannel
 {
   manager PBackground;
@@ -43,14 +45,38 @@ child:
 
   // Parent has been suspended for diversion; no more events to be enqueued.
   async FlushedForDiversion();
 
   // Child should resume processing the ChannelEventQueue, i.e. diverting any
   // OnDataAvailable and OnStopRequest messages in the queue back to the parent.
   async DivertMessages();
 
+  // Tell the child that channel classifier protection was disabled for this
+  // load.
+  async NotifyChannelClassifierProtectionDisabled(uint32_t aAcceptedReason);
+
+  // Tell the child that cookies are allowed for this load.
+  async NotifyCookieAllowed();
+
+  // Tell the child that tracking cookies are blocked for this load.
+  async NotifyCookieBlocked(uint32_t aRejectedReason);
+
+  // Tell the child that the resource being loaded has been classified.
+  async NotifyClassificationFlags(uint32_t aClassificationFlags, bool aIsThirdParty);
+
+  // Tell the child that the current channel's document is not allowed to load
+  // flash content.
+  async NotifyFlashPluginStateChanged(FlashPluginState aState);
+
+  // Tell the child information of matched URL againts SafeBrowsing list
+  async SetClassifierMatchedInfo(ClassifierInfo info);
+
+  // Tell the child information of matched URL againts SafeBrowsing tracking list
+  async SetClassifierMatchedTrackingInfo(ClassifierInfo info);
+
   async __delete__();
 
 };
 
+
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -8,25 +8,23 @@
 include protocol PNecko;
 include protocol PStreamFilter;
 include InputStreamParams;
 include URIParams;
 include PBackgroundSharedTypes;
 include NeckoChannelParams;
 include IPCServiceWorkerDescriptor;
 include IPCStream;
-include PURLClassifierInfo;
 
 include "mozilla/net/NeckoMessageUtils.h";
 
 using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
 using mozilla::net::NetAddr from "mozilla/net/DNS.h";
 using struct mozilla::net::ResourceTimingStruct from "mozilla/net/TimingStruct.h";
 using refcounted class nsIReferrerInfo from "mozilla/dom/ReferrerInfoUtils.h";
-using nsIHttpChannel::FlashPluginState from "mozilla/net/NeckoMessageUtils.h";
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 refcounted protocol PHttpChannel
 {
   manager PNecko;
@@ -191,39 +189,16 @@ child:
   async AltDataCacheInputStreamAvailable(IPCStream? stream);
 
   async OverrideReferrerInfoDuringBeginConnect(nsIReferrerInfo referrerInfo);
 
   async OnProgress(int64_t progress, int64_t progressMax);
 
   async OnStatus(nsresult status);
 
-  // Tell the child that channel classifier protection was disabled for this
-  // load.
-  async NotifyChannelClassifierProtectionDisabled(uint32_t aAcceptedReason);
-
-  // Tell the child that cookies are allowed for this load.
-  async NotifyCookieAllowed();
-
-  // Tell the child that tracking cookies are blocked for this load.
-  async NotifyCookieBlocked(uint32_t aRejectedReason);
-
-  // Tell the child that the resource being loaded has been classified.
-  async NotifyClassificationFlags(uint32_t aClassificationFlags, bool aIsThirdParty);
-
-  // Tell the child that the current channel's document is not allowed to load
-  // flash content.
-  async NotifyFlashPluginStateChanged(FlashPluginState aState);
-
-  // Tell the child information of matched URL againts SafeBrowsing list
-  async SetClassifierMatchedInfo(ClassifierInfo info);
-
-  // Tell the child information of matched URL againts SafeBrowsing tracking list
-  async SetClassifierMatchedTrackingInfo(ClassifierInfo info);
-
 both:
   // After receiving this message, the parent also calls
   // SendFinishInterceptedRedirect, and makes sure not to send any more messages
   // after that. When receiving this message, the child will call
   // Send__delete__() and complete the steps required to finish the redirect.
   async FinishInterceptedRedirect();
 
   async SetPriority(int16_t priority);
--- a/toolkit/components/antitracking/test/browser/browser.ini
+++ b/toolkit/components/antitracking/test/browser/browser.ini
@@ -124,21 +124,21 @@ support-files = localStorageEvents.html
 skip-if = fission
 support-files = workerIframe.html
 [browser_cookieBetweenTabs.js]
 [browser_partitionedMessaging.js]
 skip-if = true #Bug 1588241
 [browser_partitionedIndexedDB.js]
 skip-if = fission
 [browser_partitionedCookies.js]
-skip-if = fission
+skip-if = fission || os == "mac" || os == "win" #Bug 1590649
 support-files = cookies.sjs
 [browser_partitionedDOMCache.js]
 skip-if = fission
 [browser_partitionedServiceWorkers.js]
 skip-if = fission
 support-files = matchAll.js
 [browser_partitionedSharedWorkers.js]
-skip-if = fission
+skip-if = fission || (os == 'win') || (os == 'mac') #Bug 1590608
 support-files = sharedWorker.js partitionedSharedWorker.js
 [browser_socialtracking.js]
 skip-if = fission
 [browser_urlDecorationStripping.js]