Bug 1255894: Part 10 - Move StreamFilterParent to necko child process. r?billm,dragana draft
authorKris Maglione <maglione.k@gmail.com>
Sun, 27 Aug 2017 19:54:30 -0700
changeset 653838 b4996b098f869c3e4e8e3ae70e0caecfe6b4b8b2
parent 653837 5063880c34607d9fa6cffce2328e26c5c4501e4f
child 653839 edf8f5aceb8e54a3b0793d40af38fd25611ee632
push id76425
push usermaglione.k@gmail.com
push dateMon, 28 Aug 2017 04:09:59 +0000
reviewersbillm, dragana
bugs1255894
milestone57.0a1
Bug 1255894: Part 10 - Move StreamFilterParent to necko child process. r?billm,dragana MozReview-Commit-ID: 4JKUC7x3QgN
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
ipc/glue/BackgroundChildImpl.cpp
ipc/glue/BackgroundChildImpl.h
ipc/glue/BackgroundParentImpl.cpp
ipc/glue/BackgroundParentImpl.h
ipc/glue/PBackground.ipdl
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
toolkit/components/extensions/webrequest/PStreamFilter.ipdl
toolkit/components/extensions/webrequest/StreamFilter.cpp
toolkit/components/extensions/webrequest/StreamFilter.h
toolkit/components/extensions/webrequest/StreamFilterChild.cpp
toolkit/components/extensions/webrequest/StreamFilterChild.h
toolkit/components/extensions/webrequest/StreamFilterParent.cpp
toolkit/components/extensions/webrequest/StreamFilterParent.h
toolkit/components/extensions/webrequest/moz.build
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -53,16 +53,17 @@
 #include "mozilla/dom/PresentationParent.h"
 #include "mozilla/dom/PPresentationParent.h"
 #include "mozilla/dom/PushNotifier.h"
 #include "mozilla/dom/FlyWebPublishedServerIPC.h"
 #include "mozilla/dom/quota/QuotaManagerService.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/dom/URLClassifierParent.h"
 #include "mozilla/embedding/printingui/PrintingParent.h"
+#include "mozilla/extensions/StreamFilterParent.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/ipc/PChildToParentStreamParent.h"
 #include "mozilla/ipc/TestShellParent.h"
@@ -3309,16 +3310,29 @@ ContentParent::GetPrintingParent()
 {
   MOZ_ASSERT(mPrintingParent);
 
   RefPtr<embedding::PrintingParent> printingParent = mPrintingParent;
   return printingParent.forget();
 }
 #endif
 
+mozilla::ipc::IPCResult
+ContentParent::RecvInitStreamFilter(const uint64_t& aChannelId,
+                                    const nsString& aAddonId,
+                                    InitStreamFilterResolver&& aResolver)
+{
+  Endpoint<PStreamFilterChild> endpoint;
+  Unused << extensions::StreamFilterParent::Create(this, aChannelId, aAddonId, endpoint);
+
+  aResolver(Move(endpoint));
+
+  return IPC_OK();
+}
+
 PChildToParentStreamParent*
 ContentParent::AllocPChildToParentStreamParent()
 {
   return nsIContentParent::AllocPChildToParentStreamParent();
 }
 
 bool
 ContentParent::DeallocPChildToParentStreamParent(PChildToParentStreamParent* aActor)
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -429,16 +429,21 @@ public:
 
 #if defined(NS_PRINTING)
   /**
    * @return the PrintingParent for this ContentParent.
    */
   already_AddRefed<embedding::PrintingParent> GetPrintingParent();
 #endif
 
+  virtual mozilla::ipc::IPCResult
+  RecvInitStreamFilter(const uint64_t& aChannelId,
+                       const nsString& aAddonId,
+                       InitStreamFilterResolver&& aResolver) override;
+
   virtual PChildToParentStreamParent* AllocPChildToParentStreamParent() override;
   virtual bool
   DeallocPChildToParentStreamParent(PChildToParentStreamParent* aActor) override;
 
   virtual PParentToChildStreamParent*
   SendPParentToChildStreamConstructor(PParentToChildStreamParent*) override;
 
   virtual PFileDescriptorSetParent*
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -16,16 +16,17 @@ include protocol PHandlerService;
 include protocol PFileDescriptorSet;
 include protocol PHal;
 include protocol PHeapSnapshotTempFileHelper;
 include protocol PProcessHangMonitor;
 include protocol PImageBridge;
 include protocol PIPCBlobInputStream;
 include protocol PMedia;
 include protocol PNecko;
+include protocol PStreamFilter;
 include protocol PGMPContent;
 include protocol PGMPService;
 include protocol PPluginModule;
 include protocol PGMP;
 include protocol PPrinting;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
 include protocol POfflineCacheUpdate;
@@ -670,16 +671,19 @@ parent:
                             TabId openerTabId,
                             TabId tabId)
         returns (ContentParentId cpId, bool isForBrowser);
     sync BridgeToChildProcess(ContentParentId cpId)
         returns (Endpoint<PContentBridgeParent> endpoint);
 
     async CreateGMPService();
 
+    async InitStreamFilter(uint64_t channelId, nsString addonId)
+        returns (Endpoint<PStreamFilterChild> aEndpoint);
+
     /**
      * This call connects the content process to a plugin process. This call
      * returns an endpoint for a new PluginModuleParent. The corresponding
      * PluginModuleChild will be started up in the plugin process.
      */
     sync LoadPlugin(uint32_t aPluginId)
         returns (nsresult aResult, uint32_t aRunID, Endpoint<PPluginModuleParent> aEndpoint);
 
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -27,17 +27,16 @@
 #include "mozilla/dom/quota/PQuotaChild.h"
 #include "mozilla/dom/StorageIPC.h"
 #include "mozilla/dom/GamepadEventChannelChild.h"
 #include "mozilla/dom/GamepadTestChannelChild.h"
 #include "mozilla/dom/LocalStorage.h"
 #include "mozilla/dom/MessagePortChild.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/TabGroup.h"
-#include "mozilla/extensions/StreamFilterChild.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/PBackgroundTestChild.h"
 #include "mozilla/ipc/PChildToParentStreamChild.h"
 #include "mozilla/ipc/PParentToChildStreamChild.h"
 #include "mozilla/layout/VsyncChild.h"
 #include "mozilla/net/HttpBackgroundChannelChild.h"
 #include "mozilla/net/PUDPSocketChild.h"
 #include "mozilla/dom/network/UDPSocketChild.h"
@@ -423,36 +422,16 @@ BackgroundChildImpl::AllocPCacheStreamCo
 bool
 BackgroundChildImpl::DeallocPCacheStreamControlChild(PCacheStreamControlChild* aActor)
 {
   dom::cache::DeallocPCacheStreamControlChild(aActor);
   return true;
 }
 
 // -----------------------------------------------------------------------------
-// StreamFilter API
-// -----------------------------------------------------------------------------
-
-extensions::PStreamFilterChild*
-BackgroundChildImpl::AllocPStreamFilterChild(const uint64_t& aChannelId, const nsString& aAddonId)
-{
-  RefPtr<extensions::StreamFilterChild> agent = new extensions::StreamFilterChild();
-  return agent.forget().take();
-}
-
-bool
-BackgroundChildImpl::DeallocPStreamFilterChild(PStreamFilterChild* aActor)
-{
-  RefPtr<extensions::StreamFilterChild> child =
-    dont_AddRef(static_cast<extensions::StreamFilterChild*>(aActor));
-  MOZ_ASSERT(child);
-  return true;
-}
-
-// -----------------------------------------------------------------------------
 // MessageChannel/MessagePort API
 // -----------------------------------------------------------------------------
 
 dom::PMessagePortChild*
 BackgroundChildImpl::AllocPMessagePortChild(const nsID& aUUID,
                                             const nsID& aDestinationUUID,
                                             const uint32_t& aSequenceID)
 {
--- a/ipc/glue/BackgroundChildImpl.h
+++ b/ipc/glue/BackgroundChildImpl.h
@@ -148,23 +148,16 @@ protected:
 
   virtual PMessagePortChild*
   AllocPMessagePortChild(const nsID& aUUID, const nsID& aDestinationUUID,
                          const uint32_t& aSequenceID) override;
 
   virtual bool
   DeallocPMessagePortChild(PMessagePortChild* aActor) override;
 
-  virtual PStreamFilterChild*
-  AllocPStreamFilterChild(const uint64_t& aChannelId,
-                          const nsString& aAddonId) override;
-
-  virtual bool
-  DeallocPStreamFilterChild(PStreamFilterChild* aActor) override;
-
   virtual PChildToParentStreamChild*
   AllocPChildToParentStreamChild() override;
 
   virtual bool
   DeallocPChildToParentStreamChild(PChildToParentStreamChild* aActor) override;
 
   virtual PParentToChildStreamChild*
   AllocPParentToChildStreamChild() override;
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -25,17 +25,16 @@
 #include "mozilla/dom/ServiceWorkerRegistrar.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/ActorsParent.h"
 #include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
 #include "mozilla/dom/ipc/PendingIPCBlobParent.h"
 #include "mozilla/dom/quota/ActorsParent.h"
 #include "mozilla/dom/StorageIPC.h"
-#include "mozilla/extensions/StreamFilterParent.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/ipc/PBackgroundTestParent.h"
 #include "mozilla/ipc/PChildToParentStreamParent.h"
 #include "mozilla/ipc/PParentToChildStreamParent.h"
 #include "mozilla/layout/VsyncParent.h"
@@ -64,17 +63,16 @@ using mozilla::dom::cache::PCacheParent;
 using mozilla::dom::cache::PCacheStorageParent;
 using mozilla::dom::cache::PCacheStreamControlParent;
 using mozilla::dom::FileSystemBase;
 using mozilla::dom::FileSystemRequestParent;
 using mozilla::dom::MessagePortParent;
 using mozilla::dom::PMessagePortParent;
 using mozilla::dom::UDPSocketParent;
 using mozilla::dom::WebAuthnTransactionParent;
-using mozilla::extensions::StreamFilterParent;
 
 namespace {
 
 void
 AssertIsOnMainThread()
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
@@ -712,54 +710,16 @@ BackgroundParentImpl::AllocPCacheStreamC
 
 bool
 BackgroundParentImpl::DeallocPCacheStreamControlParent(PCacheStreamControlParent* aActor)
 {
   dom::cache::DeallocPCacheStreamControlParent(aActor);
   return true;
 }
 
-PStreamFilterParent*
-BackgroundParentImpl::AllocPStreamFilterParent(const uint64_t& aChannelId, const nsString& aAddonId)
-{
-  AssertIsInMainProcess();
-  AssertIsOnBackgroundThread();
-
-  return StreamFilterParent::Create(aChannelId, aAddonId).take();
-}
-
-mozilla::ipc::IPCResult
-BackgroundParentImpl::RecvPStreamFilterConstructor(PStreamFilterParent* aActor,
-                                                   const uint64_t& aChannelId,
-                                                   const nsString& aAddonId)
-{
-  AssertIsInMainProcess();
-  AssertIsOnBackgroundThread();
-
-  StreamFilterParent* filter = static_cast<StreamFilterParent*>(aActor);
-
-  RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(this);
-
-  filter->Init(parent.forget());
-
-  return IPC_OK();
-}
-
-bool
-BackgroundParentImpl::DeallocPStreamFilterParent(PStreamFilterParent* aActor)
-{
-  AssertIsInMainProcess();
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(aActor);
-
-  RefPtr<StreamFilterParent> filter = dont_AddRef(
-      static_cast<StreamFilterParent*>(aActor));
-  return true;
-}
-
 PMessagePortParent*
 BackgroundParentImpl::AllocPMessagePortParent(const nsID& aUUID,
                                               const nsID& aDestinationUUID,
                                               const uint32_t& aSequenceID)
 {
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
 
--- a/ipc/glue/BackgroundParentImpl.h
+++ b/ipc/glue/BackgroundParentImpl.h
@@ -13,18 +13,16 @@
 namespace mozilla {
 
 namespace layout {
 class VsyncParent;
 } // namespace layout
 
 namespace ipc {
 
-using mozilla::extensions::PStreamFilterParent;
-
 // Instances of this class should never be created directly. This class is meant
 // to be inherited in BackgroundImpl.
 class BackgroundParentImpl : public PBackgroundParent
 {
 protected:
   BackgroundParentImpl();
   virtual ~BackgroundParentImpl();
 
@@ -199,28 +197,16 @@ protected:
   virtual bool
   DeallocPMessagePortParent(PMessagePortParent* aActor) override;
 
   virtual mozilla::ipc::IPCResult
   RecvMessagePortForceClose(const nsID& aUUID,
                             const nsID& aDestinationUUID,
                             const uint32_t& aSequenceID) override;
 
-  virtual PStreamFilterParent*
-  AllocPStreamFilterParent(const uint64_t& aChannelId,
-                           const nsString& aAddonId) override;
-
-  virtual mozilla::ipc::IPCResult
-  RecvPStreamFilterConstructor(PStreamFilterParent* aActor,
-                               const uint64_t& aChannelId,
-                               const nsString& aAddonId) override;
-
-  virtual bool
-  DeallocPStreamFilterParent(PStreamFilterParent* aActor) override;
-
   virtual PAsmJSCacheEntryParent*
   AllocPAsmJSCacheEntryParent(const dom::asmjscache::OpenMode& aOpenMode,
                               const dom::asmjscache::WriteParams& aWriteParams,
                               const PrincipalInfo& aPrincipalInfo) override;
 
   virtual bool
   DeallocPAsmJSCacheEntryParent(PAsmJSCacheEntryParent* aActor) override;
 
--- a/ipc/glue/PBackground.ipdl
+++ b/ipc/glue/PBackground.ipdl
@@ -14,17 +14,16 @@ include protocol PCacheStreamControl;
 include protocol PFileDescriptorSet;
 include protocol PFileSystemRequest;
 include protocol PGamepadEventChannel;
 include protocol PGamepadTestChannel;
 include protocol PHttpBackgroundChannel;
 include protocol PIPCBlobInputStream;
 include protocol PPendingIPCBlob;
 include protocol PMessagePort;
-include protocol PStreamFilter;
 include protocol PCameras;
 include protocol PQuota;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
 include protocol PServiceWorkerManager;
 include protocol PWebAuthnTransaction;
 include protocol PUDPSocket;
 include protocol PVsync;
@@ -64,17 +63,16 @@ sync protocol PBackground
   manages PFileDescriptorSet;
   manages PFileSystemRequest;
   manages PGamepadEventChannel;
   manages PGamepadTestChannel;
   manages PHttpBackgroundChannel;
   manages PIPCBlobInputStream;
   manages PPendingIPCBlob;
   manages PMessagePort;
-  manages PStreamFilter;
   manages PCameras;
   manages PQuota;
   manages PChildToParentStream;
   manages PParentToChildStream;
   manages PServiceWorkerManager;
   manages PWebAuthnTransaction;
   manages PUDPSocket;
   manages PVsync;
@@ -109,18 +107,16 @@ parent:
   async PServiceWorkerManager();
 
   async ShutdownServiceWorkerRegistrar();
 
   async PCacheStorage(Namespace aNamespace, PrincipalInfo aPrincipalInfo);
 
   async PMessagePort(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
 
-  async PStreamFilter(uint64_t channelId, nsString addonId);
-
   async PChildToParentStream();
 
   async MessagePortForceClose(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
 
   async PAsmJSCacheEntry(OpenMode openMode,
                          WriteParams write,
                          PrincipalInfo principalInfo);
 
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -10,16 +10,17 @@
 
 #include "nsHttp.h"
 #include "nsICacheEntry.h"
 #include "mozilla/Unused.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/DocGroup.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/TabGroup.h"
+#include "mozilla/extensions/StreamFilterParent.h"
 #include "mozilla/ipc/FileDescriptorSetChild.h"
 #include "mozilla/ipc/IPCStreamUtils.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/HttpChannelChild.h"
 
 #include "AltDataOutputStreamChild.h"
 #include "CookieServiceChild.h"
 #include "HttpBackgroundChannelChild.h"
@@ -3614,16 +3615,23 @@ HttpChannelChild::ShouldInterceptURI(nsI
 
 mozilla::ipc::IPCResult
 HttpChannelChild::RecvSetPriority(const int16_t& aPriority)
 {
   mPriority = aPriority;
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+HttpChannelChild::RecvAttachStreamFilter(Endpoint<extensions::PStreamFilterParent>&& aEndpoint)
+{
+  extensions::StreamFilterParent::Attach(this, Move(aEndpoint));
+  return IPC_OK();
+}
+
 void
 HttpChannelChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // OnStartRequest might be dropped if IPDL is destroyed abnormally
   // and BackgroundChild might have pending IPC messages.
   // Clean up BackgroundChild at this time to prevent memleak.
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -159,16 +159,18 @@ protected:
   mozilla::ipc::IPCResult RecvReportSecurityMessage(const nsString& messageTag,
                                                     const nsString& messageCategory) override;
 
   mozilla::ipc::IPCResult RecvIssueDeprecationWarning(const uint32_t& warning,
                                                       const bool& asError) override;
 
   mozilla::ipc::IPCResult RecvSetPriority(const int16_t& aPriority) override;
 
+  mozilla::ipc::IPCResult RecvAttachStreamFilter(Endpoint<extensions::PStreamFilterParent>&& aEndpoint) override;
+
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   MOZ_MUST_USE bool
   GetAssociatedContentSecurity(nsIAssociatedContentSecurity** res = nullptr);
   virtual void DoNotifyListenerCleanup() override;
 
   NS_IMETHOD GetResponseSynthesized(bool* aSynthesized) override;
 
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 PNecko;
+include protocol PStreamFilter;
 include InputStreamParams;
 include URIParams;
 include PBackgroundSharedTypes;
 include NeckoChannelParams;
 
 include "mozilla/net/NeckoMessageUtils.h";
 
 using class nsHttpHeaderArray from "nsHttpHeaderArray.h";
@@ -141,16 +142,18 @@ child:
   // Tell the child to issue a deprecation warning.
   async IssueDeprecationWarning(uint32_t warning, bool asError);
 
   // When CORS blocks the request in the parent process, it doesn't have the
   // correct window ID, so send the message to the child for logging to the web
   // console.
   async LogBlockedCORSRequest(nsString message);
 
+  async AttachStreamFilter(Endpoint<PStreamFilterParent> aEndpoint);
+
 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/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -94,16 +94,17 @@
 #include "ScopedNSSTypes.h"
 #include "NullPrincipal.h"
 #include "nsIDeprecationWarner.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsICompressConvStats.h"
 #include "nsCORSListenerProxy.h"
 #include "nsISocketProvider.h"
+#include "mozilla/extensions/StreamFilterParent.h"
 #include "mozilla/net/Predictor.h"
 #include "mozilla/MathAlgorithms.h"
 #include "CacheControlParser.h"
 #include "nsMixedContentBlocker.h"
 #include "HSTSPrimerListener.h"
 #include "CacheStorageService.h"
 #include "HttpChannelParent.h"
 #include "nsIBufferedStreams.h"
@@ -6668,16 +6669,43 @@ nsHttpChannel::SetChannelIsForDownload(b
     AddClassFlags(nsIClassOfService::Throttleable);
   } else {
     ClearClassFlags(nsIClassOfService::Throttleable);
   }
 
   return HttpBaseChannel::SetChannelIsForDownload(aChannelIsForDownload);
 }
 
+base::ProcessId
+nsHttpChannel::ProcessId()
+{
+  nsCOMPtr<nsIParentChannel> parentChannel;
+  NS_QueryNotificationCallbacks(this, parentChannel);
+  RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
+  if (httpParent) {
+    return httpParent->OtherPid();
+  }
+  return base::GetCurrentProcId();
+}
+
+bool
+nsHttpChannel::AttachStreamFilter(ipc::Endpoint<extensions::PStreamFilterParent>&& aEndpoint)
+
+{
+  nsCOMPtr<nsIParentChannel> parentChannel;
+  NS_QueryNotificationCallbacks(this, parentChannel);
+  RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
+  if (httpParent) {
+    return httpParent->SendAttachStreamFilter(Move(aEndpoint));
+  }
+
+  extensions::StreamFilterParent::Attach(this, Move(aEndpoint));
+  return true;
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpChannel::nsISupportsPriority
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 nsHttpChannel::SetPriority(int32_t value)
 {
     int16_t newValue = clamped<int32_t>(value, INT16_MIN, INT16_MAX);
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -26,16 +26,17 @@
 #include "ADivertableParentChannel.h"
 #include "AutoClose.h"
 #include "nsIStreamListener.h"
 #include "nsISupportsPrimitives.h"
 #include "nsICorsPreflightCallback.h"
 #include "AlternateServices.h"
 #include "nsIHstsPrimingCallback.h"
 #include "nsIRaceCacheWithNetwork.h"
+#include "mozilla/extensions/PStreamFilterParent.h"
 #include "mozilla/Mutex.h"
 
 class nsDNSPrefetch;
 class nsICancelable;
 class nsIHttpChannelAuthProvider;
 class nsInputStreamPump;
 class nsISSLStatus;
 
@@ -286,16 +287,20 @@ public: /* internal necko use only */
     NS_IMETHOD GetResponseSynthesized(bool* aSynthesized) override;
     bool AwaitingCacheCallbacks();
     void SetCouldBeSynthesized();
 
     // Return true if the latest ODA is invoked by mCachePump.
     // Should only be called on the same thread as ODA.
     bool IsReadingFromCache() const { return mIsReadingFromCache; }
 
+    base::ProcessId ProcessId();
+
+    MOZ_MUST_USE bool AttachStreamFilter(ipc::Endpoint<extensions::PStreamFilterParent>&& aEndpoint);
+
 private: // used for alternate service validation
     RefPtr<TransactionObserver> mTransactionObserver;
 public:
     void SetConnectionInfo(nsHttpConnectionInfo *); // clones the argument
     void SetTransactionObserver(TransactionObserver *arg) { mTransactionObserver = arg; }
     TransactionObserver *GetTransactionObserver() { return mTransactionObserver; }
 
 protected:
--- a/toolkit/components/extensions/webrequest/PStreamFilter.ipdl
+++ b/toolkit/components/extensions/webrequest/PStreamFilter.ipdl
@@ -2,40 +2,35 @@
  * 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;
 
 namespace mozilla {
 namespace extensions {
 
-protocol PStreamFilter
+async protocol PStreamFilter
 {
-  manager PBackground;
-
 parent:
   async Write(uint8_t[] data);
 
   async FlushedData();
 
   async Suspend();
   async Resume();
   async Close();
   async Disconnect();
 
 child:
-  async Initialized(bool aSuccess);
   async Resumed();
   async Suspended();
   async Closed();
 
   async FlushData();
 
   async StartRequest();
   async Data(uint8_t[] data);
   async StopRequest(nsresult aStatus);
-
-  async __delete__();
 };
 
 } // namespace extensions
 } // namespace mozilla
 
--- a/toolkit/components/extensions/webrequest/StreamFilter.cpp
+++ b/toolkit/components/extensions/webrequest/StreamFilter.cpp
@@ -4,34 +4,32 @@
  * 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 "StreamFilter.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
+#include "mozilla/AbstractThread.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "mozilla/SystemGroup.h"
 #include "mozilla/extensions/StreamFilterChild.h"
 #include "mozilla/extensions/StreamFilterEvents.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "mozilla/ipc/PBackgroundChild.h"
+#include "mozilla/extensions/StreamFilterParent.h"
+#include "mozilla/dom/ContentChild.h"
 #include "nsContentUtils.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsLiteralString.h"
 #include "nsThreadUtils.h"
 #include "nsTArray.h"
 
 using namespace JS;
 using namespace mozilla::dom;
 
-using mozilla::ipc::BackgroundChild;
-using mozilla::ipc::PBackgroundChild;
-
 namespace mozilla {
 namespace extensions {
 
 /*****************************************************************************
  * Initialization
  *****************************************************************************/
 
 StreamFilter::StreamFilter(nsIGlobalObject* aParent,
@@ -40,17 +38,17 @@ StreamFilter::StreamFilter(nsIGlobalObje
   : mParent(aParent)
   , mChannelId(aRequestId)
   , mAddonId(NS_Atomize(aAddonId))
 {
   MOZ_ASSERT(aParent);
 
   mozilla::HoldJSObjects(this);
 
-  ConnectToPBackground();
+  Connect();
 };
 
 StreamFilter::~StreamFilter()
 {
   mozilla::DropJSObjects(this);
 
   if (mActor) {
     mActor->Cleanup();
@@ -68,47 +66,72 @@ StreamFilter::Create(GlobalObject& aGlob
   return filter.forget();
 }
 
 /*****************************************************************************
  * Actor allocation
  *****************************************************************************/
 
 void
-StreamFilter::ConnectToPBackground()
+StreamFilter::Connect()
 {
-  PBackgroundChild* background = BackgroundChild::GetForCurrentThread();
-  if (background) {
-    ActorCreated(background);
+  MOZ_ASSERT(!mActor);
+
+  mActor = new StreamFilterChild();
+  mActor->SetStreamFilter(this);
+
+  nsAutoString addonId;
+  mAddonId->ToString(addonId);
+
+  ContentChild* cc = ContentChild::GetSingleton();
+  if (cc) {
+    RefPtr<StreamFilter> self(this);
+
+    // This binding is technically associated with a document, so it would seem
+    // to make sense to use that document's event group. But we're processing
+    // network traffic here, and that network traffic is almost certainly
+    // associated with a different document than the binding, and that other
+    // document is the one we really care about. So we dispatch via the system
+    // group instead.
+    cc->SendInitStreamFilter(mChannelId, addonId)->Then(
+      SystemGroup::AbstractMainThreadFor(TaskCategory::Network),
+      __func__,
+      [=] (mozilla::ipc::Endpoint<PStreamFilterChild>&& aEndpoint) {
+        self->FinishConnect(Move(aEndpoint));
+      },
+      [=] (mozilla::ipc::PromiseRejectReason aReason) {
+        self->mActor->RecvInitialized(false);
+      });
   } else {
-    bool ok = BackgroundChild::GetOrCreateForCurrentThread(this);
-    MOZ_RELEASE_ASSERT(ok);
+    mozilla::ipc::Endpoint<PStreamFilterChild> endpoint;
+    Unused << StreamFilterParent::Create(nullptr, mChannelId, addonId, endpoint);
+
+    // Always dispatch asynchronously so JS callers have a chance to attach
+    // event listeners before we dispatch events.
+    SystemGroup::Dispatch(
+      TaskCategory::Network,
+      NewRunnableMethod<mozilla::ipc::Endpoint<PStreamFilterChild>&&>(
+        "StreamFilter::FinishConnect",
+        this, &StreamFilter::FinishConnect,
+        Move(endpoint)));
   }
 }
 
 void
-StreamFilter::ActorFailed()
-{
-  MOZ_CRASH("Failed to create a PBackgroundChild actor");
-}
-
-void
-StreamFilter::ActorCreated(PBackgroundChild* aBackground)
+StreamFilter::FinishConnect(mozilla::ipc::Endpoint<PStreamFilterChild>&& aEndpoint)
 {
-  MOZ_ASSERT(aBackground);
-  MOZ_ASSERT(!mActor);
-
-  nsAutoString addonId;
-  mAddonId->ToString(addonId);
+  if (aEndpoint.IsValid()) {
+    MOZ_RELEASE_ASSERT(aEndpoint.Bind(mActor));
+    mActor->RecvInitialized(true);
 
-  PStreamFilterChild* actor = aBackground->SendPStreamFilterConstructor(mChannelId, addonId);
-  MOZ_ASSERT(actor);
-
-  mActor = static_cast<StreamFilterChild*>(actor);
-  mActor->SetStreamFilter(this);
+    // IPC now owns this reference.
+    Unused << do_AddRef(mActor);
+  } else {
+    mActor->RecvInitialized(false);
+  }
 }
 
 /*****************************************************************************
  * Binding methods
  *****************************************************************************/
 
 template <typename T>
 static inline bool
@@ -264,17 +287,16 @@ JSObject*
 StreamFilter::WrapObject(JSContext* aCx, HandleObject aGivenProto)
 {
   return StreamFilterBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(StreamFilter)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(StreamFilter)
-  NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(StreamFilter)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(StreamFilter, DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
--- a/toolkit/components/extensions/webrequest/StreamFilter.h
+++ b/toolkit/components/extensions/webrequest/StreamFilter.h
@@ -4,37 +4,35 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_extensions_StreamFilter_h
 #define mozilla_extensions_StreamFilter_h
 
 #include "mozilla/dom/BindingDeclarations.h"
 #include "mozilla/dom/StreamFilterBinding.h"
+#include "mozilla/extensions/PStreamFilterChild.h"
 
 #include "mozilla/DOMEventTargetHelper.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIAtom.h"
-#include "nsIIPCBackgroundChildCreateCallback.h"
 
 namespace mozilla {
 namespace extensions {
 
 class StreamFilterChild;
 
 using namespace mozilla::dom;
 
 class StreamFilter : public DOMEventTargetHelper
-                   , public nsIIPCBackgroundChildCreateCallback
 {
   friend class StreamFilterChild;
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(StreamFilter, DOMEventTargetHelper)
 
   static already_AddRefed<StreamFilter>
   Create(GlobalObject& global,
          uint64_t aRequestId,
          const nsAString& aAddonId);
 
   explicit StreamFilter(nsIGlobalObject* aParent,
@@ -74,17 +72,20 @@ protected:
   void FireEvent(const nsAString& aType);
 
   void FireDataEvent(const nsTArray<uint8_t>& aData);
 
   void FireErrorEvent(const nsAString& aError);
 
 private:
   void
-  ConnectToPBackground();
+  Connect();
+
+  void
+  FinishConnect(mozilla::ipc::Endpoint<PStreamFilterChild>&& aEndpoint);
 
   nsCOMPtr<nsIGlobalObject> mParent;
   RefPtr<StreamFilterChild> mActor;
 
   nsString mError;
 
   const uint64_t mChannelId;
   const nsCOMPtr<nsIAtom> mAddonId;
--- a/toolkit/components/extensions/webrequest/StreamFilterChild.cpp
+++ b/toolkit/components/extensions/webrequest/StreamFilterChild.cpp
@@ -271,31 +271,30 @@ StreamFilterChild::MaybeStopRequest()
     break;
   }
 }
 
 /*****************************************************************************
  * State change acknowledgment callbacks
  *****************************************************************************/
 
-IPCResult
-StreamFilterChild::RecvInitialized(const bool& aSuccess)
+void
+StreamFilterChild::RecvInitialized(bool aSuccess)
 {
   MOZ_ASSERT(mState == State::Uninitialized);
 
   if (aSuccess) {
     mState = State::Initialized;
   } else {
     mState = State::Error;
     if (mStreamFilter) {
       mStreamFilter->FireErrorEvent(NS_LITERAL_STRING("Invalid request ID"));
       mStreamFilter = nullptr;
     }
   }
-  return IPC_OK();
 }
 
 IPCResult
 StreamFilterChild::RecvClosed() {
   MOZ_DIAGNOSTIC_ASSERT(mState == State::Closing);
 
   SetNextState();
   return IPC_OK();
@@ -502,10 +501,16 @@ StreamFilterChild::RecvData(Data&& aData
  * Glue
  *****************************************************************************/
 
 void
 StreamFilterChild::ActorDestroy(ActorDestroyReason aWhy)
 {
 }
 
+void
+StreamFilterChild::DeallocPStreamFilterChild()
+{
+  RefPtr<StreamFilterChild> self = dont_AddRef(this);
+}
+
 } // namespace extensions
 } // namespace mozilla
--- a/toolkit/components/extensions/webrequest/StreamFilterChild.h
+++ b/toolkit/components/extensions/webrequest/StreamFilterChild.h
@@ -87,29 +87,30 @@ public:
 
   State GetState() const
   {
     return mState;
   }
 
   StreamFilterStatus Status() const;
 
+  void  RecvInitialized(bool aSuccess);
+
 protected:
-  virtual IPCResult RecvInitialized(const bool& aSuccess) override;
 
   virtual IPCResult RecvStartRequest() override;
   virtual IPCResult RecvData(Data&& data) override;
   virtual IPCResult RecvStopRequest(const nsresult& aStatus) override;
 
   virtual IPCResult RecvClosed() override;
   virtual IPCResult RecvSuspended() override;
   virtual IPCResult RecvResumed() override;
   virtual IPCResult RecvFlushData() override;
 
-  virtual IPCResult Recv__delete__() override { return IPC_OK(); }
+  virtual void DeallocPStreamFilterChild() override;
 
   void
   SetStreamFilter(StreamFilter* aStreamFilter)
   {
     mStreamFilter = aStreamFilter;
   }
 
 private:
--- a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
+++ b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
@@ -3,35 +3,35 @@
 /* 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 "StreamFilterParent.h"
 
 #include "mozilla/ScopeExit.h"
 #include "mozilla/Unused.h"
-#include "mozilla/dom/nsIContentParent.h"
+#include "mozilla/dom/ContentParent.h"
+#include "nsHttpChannel.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIInputStream.h"
 #include "nsITraceableChannel.h"
 #include "nsProxyRelease.h"
+#include "nsQueryObject.h"
 #include "nsStringStream.h"
 
 namespace mozilla {
 namespace extensions {
 
 /*****************************************************************************
  * Initialization
  *****************************************************************************/
 
-StreamFilterParent::StreamFilterParent(uint64_t aChannelId, const nsAString& aAddonId)
-  : mChannelId(aChannelId)
-  , mAddonId(NS_Atomize(aAddonId))
-  , mPBackgroundThread(NS_GetCurrentThread())
+StreamFilterParent::StreamFilterParent()
+  : mActorThread(NS_GetCurrentThread())
   , mIOThread(do_GetMainThread())
   , mBufferMutex("StreamFilter buffer mutex")
   , mReceivedStop(false)
   , mSentStop(false)
   , mContext(nullptr)
   , mOffset(0)
   , mState(State::Uninitialized)
 {
@@ -40,59 +40,69 @@ StreamFilterParent::StreamFilterParent(u
 StreamFilterParent::~StreamFilterParent()
 {
   NS_ReleaseOnMainThreadSystemGroup("StreamFilterParent::mOrigListener",
                                     mOrigListener.forget());
   NS_ReleaseOnMainThreadSystemGroup("StreamFilterParent::mContext",
                                     mContext.forget());
 }
 
-void
-StreamFilterParent::Init(already_AddRefed<nsIContentParent> aContentParent)
-{
-  AssertIsPBackgroundThread();
-
-  nsCOMPtr<nsIContentParent> contentParent = aContentParent;
-
-  SystemGroup::Dispatch(
-    TaskCategory::Network,
-    NewRunnableMethod<nsCOMPtr<nsIContentParent>&&>(
-        "StreamFilterParent::DoInit",
-        this, &StreamFilterParent::DoInit, contentParent));
-}
-
-void
-StreamFilterParent::DoInit(nsCOMPtr<nsIContentParent>&& aContentParent)
+bool
+StreamFilterParent::Create(dom::ContentParent* aContentParent, uint64_t aChannelId, const nsAString& aAddonId,
+                           Endpoint<PStreamFilterChild>& aEndpoint)
 {
   AssertIsMainThread();
 
-  bool success = false;
-  auto guard = MakeScopeExit([&] {
-    RefPtr<StreamFilterParent> self(this);
-
-    RunOnPBackgroundThread(FUNC, [=] {
-      if (self->IPCActive()) {
-        self->mState = State::Initialized;
-        self->CheckResult(self->SendInitialized(success));
-      }
-    });
-  });
-
   auto webreq = WebRequestService::GetInstance();
 
-  mChannel = webreq->GetTraceableChannel(mChannelId, mAddonId, aContentParent);
-  if (NS_WARN_IF(!mChannel)) {
-    return;
+  nsCOMPtr<nsIAtom> addonId = NS_Atomize(aAddonId);
+  nsCOMPtr<nsIChannel> channel = webreq->GetTraceableChannel(aChannelId, addonId, aContentParent);
+
+  RefPtr<nsHttpChannel> chan = do_QueryObject(channel);
+  NS_ENSURE_TRUE(chan, false);
+
+  Endpoint<PStreamFilterParent> parent;
+  Endpoint<PStreamFilterChild> child;
+  nsresult rv = PStreamFilter::CreateEndpoints(chan->ProcessId(),
+                                               aContentParent ? aContentParent->OtherPid()
+                                                              : base::GetCurrentProcId(),
+                                               &parent, &child);
+  NS_ENSURE_SUCCESS(rv, false);
+
+  if (!chan->AttachStreamFilter(Move(parent))) {
+    return false;
   }
 
-  nsCOMPtr<nsITraceableChannel> traceable = do_QueryInterface(mChannel);
+  aEndpoint = Move(child);
+  return true;
+}
+
+/* static */ void
+StreamFilterParent::Attach(nsIChannel* aChannel, mozilla::ipc::Endpoint<PStreamFilterParent>&& aEndpoint)
+{
+  auto self = MakeRefPtr<StreamFilterParent>();
+  if (!aEndpoint.Bind(self)) {
+    MOZ_CRASH("Failed to attach StreamFilter endpoint");
+  }
+
+  self->Init(aChannel);
+
+  Unused << self.forget();
+}
+
+void
+StreamFilterParent::Init(nsIChannel* aChannel)
+{
+  mChannel = aChannel;
+
+  nsCOMPtr<nsITraceableChannel> traceable = do_QueryInterface(aChannel);
   MOZ_RELEASE_ASSERT(traceable);
 
   nsresult rv = traceable->SetNewListener(this, getter_AddRefs(mOrigListener));
-  success = NS_SUCCEEDED(rv);
+  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
 }
 
 /*****************************************************************************
  * nsIThreadRetargetableStreamListener
  *****************************************************************************/
 
 NS_IMETHODIMP
 StreamFilterParent::CheckListenerChain()
@@ -109,104 +119,104 @@ StreamFilterParent::CheckListenerChain()
 
 /*****************************************************************************
  * Error handling
  *****************************************************************************/
 
 void
 StreamFilterParent::Broken()
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   mState = State::Disconnecting;
 
   RefPtr<StreamFilterParent> self(this);
   RunOnIOThread(FUNC, [=] {
     self->FlushBufferedData();
 
-    RunOnPBackgroundThread(FUNC, [=] {
+    RunOnActorThread(FUNC, [=] {
       if (self->IPCActive()) {
         self->mState = State::Disconnected;
       }
     });
   });
 }
 
 /*****************************************************************************
  * State change requests
  *****************************************************************************/
 
 IPCResult
 StreamFilterParent::RecvClose()
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   mState = State::Closed;
 
   if (!mSentStop) {
     RefPtr<StreamFilterParent> self(this);
     RunOnMainThread(FUNC, [=] {
       nsresult rv = self->EmitStopRequest(NS_OK);
       Unused << NS_WARN_IF(NS_FAILED(rv));
     });
   }
 
-  Unused << Send__delete__(this);
+  Close();
   return IPC_OK();
 }
 
 IPCResult
 StreamFilterParent::RecvSuspend()
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   if (mState == State::TransferringData) {
     RefPtr<StreamFilterParent> self(this);
     RunOnMainThread(FUNC, [=] {
       self->mChannel->Suspend();
 
-      RunOnPBackgroundThread(FUNC, [=] {
+      RunOnActorThread(FUNC, [=] {
         if (IPCActive()) {
           mState = State::Suspended;
           CheckResult(SendSuspended());
         }
       });
     });
   }
   return IPC_OK();
 }
 
 IPCResult
 StreamFilterParent::RecvResume()
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   if (mState == State::Suspended) {
     // Change state before resuming so incoming data is handled correctly
     // immediately after resuming.
     mState = State::TransferringData;
 
     RefPtr<StreamFilterParent> self(this);
     RunOnMainThread(FUNC, [=] {
       self->mChannel->Resume();
 
-      RunOnPBackgroundThread(FUNC, [=] {
+      RunOnActorThread(FUNC, [=] {
         if (self->IPCActive()) {
           self->CheckResult(self->SendResumed());
         }
       });
     });
   }
   return IPC_OK();
 }
 
 IPCResult
 StreamFilterParent::RecvDisconnect()
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   if (mState == State::Suspended) {
   RefPtr<StreamFilterParent> self(this);
     RunOnMainThread(FUNC, [=] {
       self->mChannel->Resume();
     });
   } else if (mState != State::TransferringData) {
     return IPC_OK();
@@ -215,41 +225,41 @@ StreamFilterParent::RecvDisconnect()
   mState = State::Disconnecting;
   CheckResult(SendFlushData());
   return IPC_OK();
 }
 
 IPCResult
 StreamFilterParent::RecvFlushedData()
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   MOZ_ASSERT(mState == State::Disconnecting);
 
-  Unused << Send__delete__(this);
+  Close();
 
   RefPtr<StreamFilterParent> self(this);
   RunOnIOThread(FUNC, [=] {
     self->FlushBufferedData();
 
-    RunOnPBackgroundThread(FUNC, [=] {
+    RunOnActorThread(FUNC, [=] {
       self->mState = State::Disconnected;
     });
   });
   return IPC_OK();
 }
 
 /*****************************************************************************
  * Data output
  *****************************************************************************/
 
 IPCResult
 StreamFilterParent::RecvWrite(Data&& aData)
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   mIOThread->Dispatch(
     NewRunnableMethod<Data&&>("StreamFilterParent::WriteMove",
                               this,
                               &StreamFilterParent::WriteMove,
                               Move(aData)),
     NS_DISPATCH_NORMAL);
   return IPC_OK();
@@ -289,17 +299,17 @@ NS_IMETHODIMP
 StreamFilterParent::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
 {
   AssertIsMainThread();
 
   mContext = aContext;
 
   if (mState != State::Disconnected) {
     RefPtr<StreamFilterParent> self(this);
-    RunOnPBackgroundThread(FUNC, [=] {
+    RunOnActorThread(FUNC, [=] {
       if (self->IPCActive()) {
         self->mState = State::TransferringData;
         self->CheckResult(self->SendStartRequest());
       }
     });
   }
 
   return mOrigListener->OnStartRequest(aRequest, aContext);
@@ -313,17 +323,17 @@ StreamFilterParent::OnStopRequest(nsIReq
   AssertIsMainThread();
 
   mReceivedStop = true;
   if (mState == State::Disconnected) {
     return EmitStopRequest(aStatusCode);
   }
 
   RefPtr<StreamFilterParent> self(this);
-  RunOnPBackgroundThread(FUNC, [=] {
+  RunOnActorThread(FUNC, [=] {
     if (self->IPCActive()) {
       self->CheckResult(self->SendStopRequest(aStatusCode));
     }
   });
   return NS_OK;
 }
 
 nsresult
@@ -338,17 +348,17 @@ StreamFilterParent::EmitStopRequest(nsre
 
 /*****************************************************************************
  * Incoming data handling
  *****************************************************************************/
 
 void
 StreamFilterParent::DoSendData(Data&& aData)
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   if (mState == State::TransferringData) {
     CheckResult(SendData(aData));
   }
 }
 
 NS_IMETHODIMP
 StreamFilterParent::OnDataAvailable(nsIRequest* aRequest,
@@ -388,17 +398,17 @@ StreamFilterParent::OnDataAvailable(nsIR
   NS_ENSURE_TRUE(count == aCount, NS_ERROR_UNEXPECTED);
 
   if (mState == State::Disconnecting) {
     MutexAutoLock al(mBufferMutex);
     BufferData(Move(data));
   } else if (mState == State::Closed) {
     return NS_ERROR_FAILURE;
   } else {
-    mPBackgroundThread->Dispatch(
+    mActorThread->Dispatch(
       NewRunnableMethod<Data&&>("StreamFilterParent::DoSendData",
                                 this,
                                 &StreamFilterParent::DoSendData,
                                 Move(data)),
       NS_DISPATCH_NORMAL);
   }
   return NS_OK;
 }
@@ -433,20 +443,26 @@ StreamFilterParent::FlushBufferedData()
 
 /*****************************************************************************
  * Glue
  *****************************************************************************/
 
 void
 StreamFilterParent::ActorDestroy(ActorDestroyReason aWhy)
 {
-  AssertIsPBackgroundThread();
+  AssertIsActorThread();
 
   if (mState != State::Disconnected && mState != State::Closed) {
     Broken();
   }
 }
 
+void
+StreamFilterParent::DeallocPStreamFilterParent()
+{
+  RefPtr<StreamFilterParent> self = dont_AddRef(this);
+}
+
 NS_IMPL_ISUPPORTS(StreamFilterParent, nsIStreamListener, nsIRequestObserver, nsIThreadRetargetableStreamListener)
 
 } // namespace extensions
 } // namespace mozilla
 
--- a/toolkit/components/extensions/webrequest/StreamFilterParent.h
+++ b/toolkit/components/extensions/webrequest/StreamFilterParent.h
@@ -22,17 +22,20 @@
 #if defined(_MSC_VER)
 #  define FUNC __FUNCSIG__
 #else
 #  define FUNC __PRETTY_FUNCTION__
 #endif
 
 namespace mozilla {
 namespace dom {
-  class nsIContentParent;
+  class ContentParent;
+}
+namespace net {
+  class nsHttpChannel;
 }
 
 namespace extensions {
 
 using namespace mozilla::dom;
 using mozilla::ipc::IPCResult;
 
 class StreamFilterParent final
@@ -42,17 +45,23 @@ class StreamFilterParent final
   , public StreamFilterBase
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
 
-  explicit StreamFilterParent(uint64_t aChannelId, const nsAString& aAddonId);
+  StreamFilterParent();
+
+  static bool Create(ContentParent* aContentParent,
+                     uint64_t aChannelId, const nsAString& aAddonId,
+                     mozilla::ipc::Endpoint<PStreamFilterChild>& aEndpoint);
+
+  static void Attach(nsIChannel* aChannel, mozilla::ipc::Endpoint<PStreamFilterParent>&& aEndpoint);
 
   enum class State
   {
     // The parent has been created, but not yet constructed by the child.
     Uninitialized,
     // The parent has been successfully constructed.
     Initialized,
     // The OnRequestStarted event has been received, and data is being
@@ -67,44 +76,37 @@ public:
     // currnetly in transit to, or buffered by, the child will be written to the
     // output listener before we enter the Disconnected atate.
     Disconnecting,
     // The channel has been disconnected from the child, and all further data
     // and events will be passed directly to the output listener.
     Disconnected,
   };
 
-  static already_AddRefed<StreamFilterParent>
-  Create(uint64_t aChannelId, const nsAString& aAddonId)
-  {
-    RefPtr<StreamFilterParent> filter = new StreamFilterParent(aChannelId, aAddonId);
-    return filter.forget();
-  }
-
-  void Init(already_AddRefed<nsIContentParent> aContentParent);
-
 protected:
   virtual ~StreamFilterParent();
 
   virtual IPCResult RecvWrite(Data&& aData) override;
   virtual IPCResult RecvFlushedData() override;
   virtual IPCResult RecvSuspend() override;
   virtual IPCResult RecvResume() override;
   virtual IPCResult RecvClose() override;
   virtual IPCResult RecvDisconnect() override;
 
+  virtual void DeallocPStreamFilterParent() override;
+
 private:
   bool IPCActive()
   {
     return (mState != State::Closed &&
             mState != State::Disconnecting &&
             mState != State::Disconnected);
   }
 
-  void DoInit(nsCOMPtr<nsIContentParent>&& aContentParent);
+  void Init(nsIChannel* aChannel);
 
   nsresult FlushBufferedData();
 
   nsresult Write(Data& aData);
 
   void WriteMove(Data&& aData);
 
   void DoSendData(Data&& aData);
@@ -119,64 +121,61 @@ private:
   CheckResult(bool aResult)
   {
     if (NS_WARN_IF(!aResult)) {
       Broken();
     }
   }
 
   void
-  AssertIsPBackgroundThread()
+  AssertIsActorThread()
   {
-    MOZ_ASSERT(NS_GetCurrentThread() == mPBackgroundThread);
+    MOZ_ASSERT(NS_GetCurrentThread() == mActorThread);
   }
 
   void
   AssertIsIOThread()
   {
     MOZ_ASSERT(NS_GetCurrentThread() == mIOThread);
   }
 
-  void
+  static void
   AssertIsMainThread()
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
   template<typename Function>
   void
   RunOnMainThread(const char* aName, Function&& aFunc)
   {
     SystemGroup::Dispatch(TaskCategory::Network,
                           Move(NS_NewRunnableFunction(aName, aFunc)));
   }
 
   template<typename Function>
   void
-  RunOnPBackgroundThread(const char* aName, Function&& aFunc)
+  RunOnActorThread(const char* aName, Function&& aFunc)
   {
-    mPBackgroundThread->Dispatch(Move(NS_NewRunnableFunction(aName, aFunc)),
-                                 NS_DISPATCH_NORMAL);
+    mActorThread->Dispatch(Move(NS_NewRunnableFunction(aName, aFunc)),
+                           NS_DISPATCH_NORMAL);
   }
 
   template<typename Function>
   void
   RunOnIOThread(const char* aName, Function&& aFunc)
   {
     mIOThread->Dispatch(Move(NS_NewRunnableFunction(aName, aFunc)),
                         NS_DISPATCH_NORMAL);
   }
 
-  const uint64_t mChannelId;
-  const nsCOMPtr<nsIAtom> mAddonId;
-
   nsCOMPtr<nsIChannel> mChannel;
   nsCOMPtr<nsIStreamListener> mOrigListener;
 
-  nsCOMPtr<nsIThread> mPBackgroundThread;
+  nsCOMPtr<nsIThread> mActorThread;
   nsCOMPtr<nsIThread> mIOThread;
 
   Mutex mBufferMutex;
 
   bool mReceivedStop;
   bool mSentStop;
 
   nsCOMPtr<nsISupports> mContext;
--- a/toolkit/components/extensions/webrequest/moz.build
+++ b/toolkit/components/extensions/webrequest/moz.build
@@ -37,12 +37,18 @@ EXPORTS.mozilla.extensions += [
     'StreamFilterBase.h',
     'StreamFilterChild.h',
     'StreamFilterEvents.h',
     'StreamFilterParent.h',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
+LOCAL_INCLUDES += [
+    # For nsHttpChannel.h
+    '/netwerk/base',
+    '/netwerk/protocol/http',
+]
+
 FINAL_LIBRARY = 'xul'
 
 with Files("**"):
     BUG_COMPONENT = ("Toolkit", "WebExtensions: Request Handling")