Backed out 22 changesets (bug 1231213) for Browser-chrome failures on /workers/remoteworkers/RemoteWorkerChild.cpp
authorDorel Luca <dluca@mozilla.com>
Thu, 15 Aug 2019 01:04:46 +0300
changeset 488036 3cf55b7f12f2cb7dfcdbcbcd817d77e298e76fbd
parent 488035 6e1475b54a6f295293465692e81f2b950cca3584
child 488037 f48c581ece1bfd0f54d206d9f7d3bdf17789eded
push id36434
push usercbrindusan@mozilla.com
push dateThu, 15 Aug 2019 09:44:30 +0000
treeherdermozilla-central@144fbfb409b7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1231213
milestone70.0a1
backs out7e09ad9ceea6cc1dafe35ceed18af6a8b3bc007b
a275eb0b1a191cce3d7b6461ee6b816b3d87ddac
906b80778539e1362a444033c435759d01dfe7f0
6a40ab6852cb51e9903751b04d797c5d53549fa5
216591953f9750051e8915543aa246d4ec1600bb
1de357bc192118732798e8dd56e44e137add019b
8e3fedf6502a968ae89119615d798aba5b14f608
1b9a8b022fce17c513ec0af3dff3ffd6db88c33d
85df1959eb98a95bf7aa59332d366ebb3f45d1eb
666bf42600469276c778a9ab9a4e1324eccd02ea
0b03a19a6dc141f49ead7555b200e5b7498124c0
11f010e6d6e7166b92c2638832896962bd8a71a7
6ed55807374f0ba63a36990d06200f77baf713a6
395062aef2ec1c0abd3b1426fb376f5fef3e0c11
bacf8499ba7b2caf600a8fef352baf7df3a69d6d
bf5d60c7a85a2444df3a3740c5daeb230a87e248
cd434b787ce62199119834aeafcaebd4ed53d1fc
ee456510421792f47aae2880e8680e5636e46dfd
581653ef33ddb0bf5b054ba455d5108dbb2cfa1a
2d5628a0e52dc9aff4a67fa05da6d238793f9af6
3449c2eba4c6b196fc3f0be090a5aa48058b8173
ae221b6288996b15104e52c497e2cae59da9f536
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 22 changesets (bug 1231213) for Browser-chrome failures on /workers/remoteworkers/RemoteWorkerChild.cpp Backed out changeset 7e09ad9ceea6 (bug 1231213) Backed out changeset a275eb0b1a19 (bug 1231213) Backed out changeset 906b80778539 (bug 1231213) Backed out changeset 6a40ab6852cb (bug 1231213) Backed out changeset 216591953f97 (bug 1231213) Backed out changeset 1de357bc1921 (bug 1231213) Backed out changeset 8e3fedf6502a (bug 1231213) Backed out changeset 1b9a8b022fce (bug 1231213) Backed out changeset 85df1959eb98 (bug 1231213) Backed out changeset 666bf4260046 (bug 1231213) Backed out changeset 0b03a19a6dc1 (bug 1231213) Backed out changeset 11f010e6d6e7 (bug 1231213) Backed out changeset 6ed55807374f (bug 1231213) Backed out changeset 395062aef2ec (bug 1231213) Backed out changeset bacf8499ba7b (bug 1231213) Backed out changeset bf5d60c7a85a (bug 1231213) Backed out changeset cd434b787ce6 (bug 1231213) Backed out changeset ee4565104217 (bug 1231213) Backed out changeset 581653ef33dd (bug 1231213) Backed out changeset 2d5628a0e52d (bug 1231213) Backed out changeset 3449c2eba4c6 (bug 1231213) Backed out changeset ae221b628899 (bug 1231213)
dom/abort/moz.build
dom/console/moz.build
dom/fetch/FetchTypes.ipdlh
dom/fetch/InternalRequest.cpp
dom/fetch/InternalRequest.h
dom/fetch/InternalResponse.cpp
dom/fetch/InternalResponse.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/URLClassifierParent.h
dom/media/webrtc/PMediaTransport.ipdl
dom/notification/Notification.cpp
dom/performance/moz.build
dom/serviceworkers/FetchEventOpChild.cpp
dom/serviceworkers/FetchEventOpChild.h
dom/serviceworkers/FetchEventOpParent.cpp
dom/serviceworkers/FetchEventOpParent.h
dom/serviceworkers/FetchEventOpProxyChild.cpp
dom/serviceworkers/FetchEventOpProxyChild.h
dom/serviceworkers/FetchEventOpProxyParent.cpp
dom/serviceworkers/FetchEventOpProxyParent.h
dom/serviceworkers/PFetchEventOp.ipdl
dom/serviceworkers/PFetchEventOpProxy.ipdl
dom/serviceworkers/ServiceWorkerEvents.cpp
dom/serviceworkers/ServiceWorkerEvents.h
dom/serviceworkers/ServiceWorkerInfo.cpp
dom/serviceworkers/ServiceWorkerManager.cpp
dom/serviceworkers/ServiceWorkerManager.h
dom/serviceworkers/ServiceWorkerOp.cpp
dom/serviceworkers/ServiceWorkerOp.h
dom/serviceworkers/ServiceWorkerOpArgs.ipdlh
dom/serviceworkers/ServiceWorkerOpPromise.h
dom/serviceworkers/ServiceWorkerPrivate.cpp
dom/serviceworkers/ServiceWorkerPrivate.h
dom/serviceworkers/ServiceWorkerPrivateImpl.cpp
dom/serviceworkers/ServiceWorkerPrivateImpl.h
dom/serviceworkers/ServiceWorkerRegistration.cpp
dom/serviceworkers/ServiceWorkerRegistrationChild.cpp
dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
dom/serviceworkers/ServiceWorkerRegistrationInfo.h
dom/serviceworkers/ServiceWorkerRegistrationProxy.cpp
dom/serviceworkers/ServiceWorkerShutdownBlocker.cpp
dom/serviceworkers/ServiceWorkerShutdownBlocker.h
dom/serviceworkers/moz.build
dom/workers/WorkerError.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/WorkerScope.cpp
dom/workers/moz.build
dom/workers/remoteworkers/PRemoteWorker.ipdl
dom/workers/remoteworkers/PRemoteWorkerController.ipdl
dom/workers/remoteworkers/RemoteWorkerChild.cpp
dom/workers/remoteworkers/RemoteWorkerChild.h
dom/workers/remoteworkers/RemoteWorkerController.cpp
dom/workers/remoteworkers/RemoteWorkerController.h
dom/workers/remoteworkers/RemoteWorkerControllerChild.cpp
dom/workers/remoteworkers/RemoteWorkerControllerChild.h
dom/workers/remoteworkers/RemoteWorkerControllerParent.cpp
dom/workers/remoteworkers/RemoteWorkerControllerParent.h
dom/workers/remoteworkers/RemoteWorkerManager.cpp
dom/workers/remoteworkers/RemoteWorkerManager.h
dom/workers/remoteworkers/RemoteWorkerParent.cpp
dom/workers/remoteworkers/RemoteWorkerParent.h
dom/workers/remoteworkers/RemoteWorkerTypes.ipdlh
dom/workers/remoteworkers/moz.build
dom/workers/sharedworkers/SharedWorker.cpp
ipc/glue/BackgroundChildImpl.cpp
ipc/glue/BackgroundChildImpl.h
ipc/glue/BackgroundParentImpl.cpp
ipc/glue/BackgroundParentImpl.h
ipc/glue/IPCStreamSource.cpp
ipc/glue/PBackground.ipdl
netwerk/base/nsBufferedStreams.cpp
netwerk/base/nsBufferedStreams.h
netwerk/base/nsNetUtil.cpp
netwerk/ipc/NeckoMessageUtils.h
testing/web-platform/meta/service-workers/service-worker/multiple-update.https.html.ini
testing/web-platform/meta/service-workers/service-worker/update-not-allowed.https.html.ini
testing/web-platform/tests/service-workers/service-worker/resources/update-during-installation-worker.js
--- a/dom/abort/moz.build
+++ b/dom/abort/moz.build
@@ -14,11 +14,9 @@ EXPORTS.mozilla.dom += [
     'AbortSignal.h',
 ]
 
 UNIFIED_SOURCES += [
     'AbortController.cpp',
     'AbortSignal.cpp',
 ]
 
-include('/ipc/chromium/chromium-config.mozbuild')
-
 FINAL_LIBRARY = 'xul'
--- a/dom/console/moz.build
+++ b/dom/console/moz.build
@@ -47,11 +47,9 @@ LOCAL_INCLUDES += [
     '/dom/base',
     '/js/xpconnect/src',
 ]
 
 MOCHITEST_MANIFESTS += [ 'tests/mochitest.ini' ]
 MOCHITEST_CHROME_MANIFESTS += [ 'tests/chrome.ini' ]
 XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
 
-include('/ipc/chromium/chromium-config.mozbuild')
-
 FINAL_LIBRARY = 'xul'
--- a/dom/fetch/FetchTypes.ipdlh
+++ b/dom/fetch/FetchTypes.ipdlh
@@ -2,62 +2,20 @@
  * 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 IPCStream;
 include ChannelInfo;
 include PBackgroundSharedTypes;
 
 using HeadersGuardEnum from "mozilla/dom/FetchIPCTypes.h";
-using ReferrerPolicy from "mozilla/dom/FetchIPCTypes.h";
-using RequestCache from "mozilla/dom/FetchIPCTypes.h";
-using RequestCredentials from "mozilla/dom/FetchIPCTypes.h";
-using RequestMode from "mozilla/dom/FetchIPCTypes.h";
-using RequestRedirect from "mozilla/dom/FetchIPCTypes.h";
-using ResponseType from "mozilla/dom/FetchIPCTypes.h";
 
 namespace mozilla {
 namespace dom {
 
-struct HeadersEntry {
+struct HeadersEntry
+{
   nsCString name;
   nsCString value;
 };
 
-struct IPCInternalRequest {
-  nsCString method;
-  nsCString[] urlList;
-  HeadersGuardEnum headersGuard;
-  HeadersEntry[] headers;
-  IPCStream? body;
-  int64_t bodySize;
-  nsCString preferredAlternativeDataType;
-  uint32_t contentPolicyType;
-  nsString referrer;
-  ReferrerPolicy referrerPolicy;
-  RequestMode requestMode;
-  RequestCredentials requestCredentials;
-  RequestCache cacheMode;
-  RequestRedirect requestRedirect;
-  nsString integrity;
-  nsCString fragment;
-  bool createdByFetchEvent;
-  PrincipalInfo? principalInfo;
-};
-
-struct IPCInternalResponse {
-  ResponseType type;
-  nsCString[] urlList;
-  uint16_t status;
-  nsCString statusText;
-  HeadersGuardEnum headersGuard;
-  HeadersEntry[] headers;
-  IPCStream? body;
-  int64_t bodySize;
-  nsresult errorCode;
-  nsCString alternativeDataType;
-  IPCStream? alternativeBody;
-  IPCChannelInfo channelInfo;
-  PrincipalInfo? principalInfo;
-};
-
 } // namespace ipc
 } // namespace mozilla
--- a/dom/fetch/InternalRequest.cpp
+++ b/dom/fetch/InternalRequest.cpp
@@ -11,18 +11,16 @@
 #include "nsStreamUtils.h"
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/FetchTypes.h"
 #include "mozilla/dom/ScriptSettings.h"
 
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/dom/WorkerPrivate.h"
-#include "mozilla/ipc/IPCStreamUtils.h"
-#include "mozilla/ipc/PBackgroundChild.h"
 
 namespace mozilla {
 namespace dom {
 // The global is used to extract the principal.
 already_AddRefed<InternalRequest> InternalRequest::GetRequestConstructorCopy(
     nsIGlobalObject* aGlobal, ErrorResult& aRv) const {
   MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
                      "Internal Request's urlList should not be empty when "
@@ -168,83 +166,18 @@ InternalRequest::InternalRequest(const I
       mSynchronous(aOther.mSynchronous),
       mUnsafeRequest(aOther.mUnsafeRequest),
       mUseURLCredentials(aOther.mUseURLCredentials),
       mCreatedByFetchEvent(aOther.mCreatedByFetchEvent),
       mContentPolicyTypeOverridden(aOther.mContentPolicyTypeOverridden) {
   // NOTE: does not copy body stream... use the fallible Clone() for that
 }
 
-InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
-    : mMethod(aIPCRequest.method()),
-      mURLList(aIPCRequest.urlList()),
-      mHeaders(new InternalHeaders(aIPCRequest.headers(),
-                                   aIPCRequest.headersGuard())),
-      mBodyStream(mozilla::ipc::DeserializeIPCStream(aIPCRequest.body())),
-      mBodyLength(aIPCRequest.bodySize()),
-      mPreferredAlternativeDataType(aIPCRequest.preferredAlternativeDataType()),
-      mContentPolicyType(
-          static_cast<nsContentPolicyType>(aIPCRequest.contentPolicyType())),
-      mReferrer(aIPCRequest.referrer()),
-      mReferrerPolicy(aIPCRequest.referrerPolicy()),
-      mMode(aIPCRequest.requestMode()),
-      mCredentialsMode(aIPCRequest.requestCredentials()),
-      mCacheMode(aIPCRequest.cacheMode()),
-      mRedirectMode(aIPCRequest.requestRedirect()),
-      mIntegrity(aIPCRequest.integrity()),
-      mFragment(aIPCRequest.fragment()),
-      mCreatedByFetchEvent(aIPCRequest.createdByFetchEvent()) {
-  if (aIPCRequest.principalInfo()) {
-    mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(
-        aIPCRequest.principalInfo().ref());
-  }
-}
-
 InternalRequest::~InternalRequest() {}
 
-template void InternalRequest::ToIPC<mozilla::ipc::PBackgroundChild>(
-    IPCInternalRequest* aIPCRequest, mozilla::ipc::PBackgroundChild* aManager,
-    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
-
-template <typename M>
-void InternalRequest::ToIPC(
-    IPCInternalRequest* aIPCRequest, M* aManager,
-    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream) {
-  MOZ_ASSERT(aIPCRequest);
-  MOZ_ASSERT(aManager);
-  MOZ_ASSERT(!mURLList.IsEmpty());
-
-  aIPCRequest->method() = mMethod;
-  aIPCRequest->urlList() = mURLList;
-  mHeaders->ToIPC(aIPCRequest->headers(), aIPCRequest->headersGuard());
-
-  if (mBodyStream) {
-    aAutoStream.reset(new mozilla::ipc::AutoIPCStream(aIPCRequest->body()));
-    DebugOnly<bool> ok = aAutoStream->Serialize(mBodyStream, aManager);
-    MOZ_ASSERT(ok);
-  }
-
-  aIPCRequest->bodySize() = mBodyLength;
-  aIPCRequest->preferredAlternativeDataType() = mPreferredAlternativeDataType;
-  aIPCRequest->contentPolicyType() = static_cast<uint32_t>(mContentPolicyType);
-  aIPCRequest->referrer() = mReferrer;
-  aIPCRequest->referrerPolicy() = mReferrerPolicy;
-  aIPCRequest->requestMode() = mMode;
-  aIPCRequest->requestCredentials() = mCredentialsMode;
-  aIPCRequest->cacheMode() = mCacheMode;
-  aIPCRequest->requestRedirect() = mRedirectMode;
-  aIPCRequest->integrity() = mIntegrity;
-  aIPCRequest->fragment() = mFragment;
-  aIPCRequest->createdByFetchEvent() = mCreatedByFetchEvent;
-
-  if (mPrincipalInfo) {
-    aIPCRequest->principalInfo().emplace(*mPrincipalInfo);
-  }
-}
-
 void InternalRequest::SetContentPolicyType(
     nsContentPolicyType aContentPolicyType) {
   mContentPolicyType = aContentPolicyType;
 }
 
 void InternalRequest::OverrideContentPolicyType(
     nsContentPolicyType aContentPolicyType) {
   SetContentPolicyType(aContentPolicyType);
--- a/dom/fetch/InternalRequest.h
+++ b/dom/fetch/InternalRequest.h
@@ -7,32 +7,30 @@
 #ifndef mozilla_dom_InternalRequest_h
 #define mozilla_dom_InternalRequest_h
 
 #include "mozilla/dom/HeadersBinding.h"
 #include "mozilla/dom/InternalHeaders.h"
 #include "mozilla/dom/RequestBinding.h"
 #include "mozilla/LoadTainting.h"
 #include "mozilla/net/ReferrerPolicy.h"
-#include "mozilla/UniquePtr.h"
 
 #include "nsIContentPolicy.h"
 #include "nsIInputStream.h"
 #include "nsISupportsImpl.h"
 #ifdef DEBUG
 #  include "nsIURLParser.h"
 #  include "nsNetCID.h"
 #  include "nsServiceManagerUtils.h"
 #endif
 
 namespace mozilla {
 
 namespace ipc {
 class PrincipalInfo;
-class AutoIPCStream;
 }  // namespace ipc
 
 namespace dom {
 
 /*
  * The mapping of RequestDestination and nsContentPolicyType is currently as the
  * following.  Note that this mapping is not perfect yet (see the TODO comments
  * below for examples).
@@ -65,17 +63,16 @@ namespace dom {
  * track             | TYPE_INTERNAL_TRACK
  * video             | TYPE_INTERNAL_VIDEO
  * worker            | TYPE_INTERNAL_WORKER
  * xslt              | TYPE_XSLT
  * _empty            | Default for everything else.
  *
  */
 
-class IPCInternalRequest;
 class Request;
 
 #define kFETCH_CLIENT_REFERRER_STR "about:client"
 class InternalRequest final {
   friend class Request;
 
  public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest)
@@ -85,22 +82,16 @@ class InternalRequest final {
                   already_AddRefed<InternalHeaders> aHeaders,
                   RequestCache aCacheMode, RequestMode aMode,
                   RequestRedirect aRequestRedirect,
                   RequestCredentials aRequestCredentials,
                   const nsAString& aReferrer, ReferrerPolicy aReferrerPolicy,
                   nsContentPolicyType aContentPolicyType,
                   const nsAString& aIntegrity);
 
-  explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
-
-  template <typename M>
-  void ToIPC(IPCInternalRequest* aIPCRequest, M* aManager,
-             UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
-
   already_AddRefed<InternalRequest> Clone();
 
   void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
 
   void SetMethod(const nsACString& aMethod) { mMethod.Assign(aMethod); }
 
   bool HasSimpleMethod() const {
     return mMethod.LowerCaseEqualsASCII("get") ||
--- a/dom/fetch/InternalResponse.cpp
+++ b/dom/fetch/InternalResponse.cpp
@@ -2,18 +2,16 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "InternalResponse.h"
 
 #include "mozilla/Assertions.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/dom/FetchTypes.h"
 #include "mozilla/dom/InternalHeaders.h"
 #include "mozilla/dom/cache/CacheTypes.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/ipc/IPCStreamUtils.h"
 #include "mozilla/RandomNum.h"
 #include "nsIRandomGenerator.h"
 #include "nsIURI.h"
 #include "nsStreamUtils.h"
@@ -36,122 +34,18 @@ InternalResponse::InternalResponse(uint1
       mStatus(aStatus),
       mStatusText(aStatusText),
       mHeaders(new InternalHeaders(HeadersGuardEnum::Response)),
       mBodySize(UNKNOWN_BODY_SIZE),
       mPaddingSize(UNKNOWN_PADDING_SIZE),
       mErrorCode(NS_OK),
       mCredentialsMode(aCredentialsMode) {}
 
-/* static */ RefPtr<InternalResponse> InternalResponse::FromIPC(
-    const IPCInternalResponse& aIPCResponse) {
-  if (aIPCResponse.type() == ResponseType::Error) {
-    return InternalResponse::NetworkError(aIPCResponse.errorCode());
-  }
-
-  RefPtr<InternalResponse> response =
-      new InternalResponse(aIPCResponse.status(), aIPCResponse.statusText());
-
-  response->SetURLList(aIPCResponse.urlList());
-  response->mHeaders =
-      new InternalHeaders(aIPCResponse.headers(), aIPCResponse.headersGuard());
-
-  nsCOMPtr<nsIInputStream> body =
-      mozilla::ipc::DeserializeIPCStream(aIPCResponse.body());
-  response->SetBody(body, aIPCResponse.bodySize());
-
-  response->SetAlternativeDataType(aIPCResponse.alternativeDataType());
-
-  nsCOMPtr<nsIInputStream> alternativeBody =
-      mozilla::ipc::DeserializeIPCStream(aIPCResponse.alternativeBody());
-  response->SetAlternativeBody(alternativeBody);
-
-  response->InitChannelInfo(aIPCResponse.channelInfo());
-
-  if (aIPCResponse.principalInfo()) {
-    response->SetPrincipalInfo(MakeUnique<mozilla::ipc::PrincipalInfo>(
-        aIPCResponse.principalInfo().ref()));
-  }
-
-  switch (aIPCResponse.type()) {
-    case ResponseType::Basic:
-      response = response->BasicResponse();
-      break;
-    case ResponseType::Cors:
-      response = response->CORSResponse();
-      break;
-    case ResponseType::Default:
-      break;
-    case ResponseType::Opaque:
-      response = response->OpaqueResponse();
-      break;
-    case ResponseType::Opaqueredirect:
-      response = response->OpaqueRedirectResponse();
-      break;
-    default:
-      MOZ_CRASH("Unexpected ResponseType!");
-  }
-
-  MOZ_ASSERT(response);
-
-  return response;
-}
-
 InternalResponse::~InternalResponse() {}
 
-template void InternalResponse::ToIPC<mozilla::ipc::PBackgroundChild>(
-    IPCInternalResponse* aIPCResponse, mozilla::ipc::PBackgroundChild* aManager,
-    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
-    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
-
-template <typename M>
-void InternalResponse::ToIPC(
-    IPCInternalResponse* aIPCResponse, M* aManager,
-    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
-    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream) {
-  MOZ_ASSERT(aIPCResponse);
-
-  aIPCResponse->type() = mType;
-  GetUnfilteredURLList(aIPCResponse->urlList());
-  aIPCResponse->status() = GetUnfilteredStatus();
-  aIPCResponse->statusText() = GetUnfilteredStatusText();
-  UnfilteredHeaders()->ToIPC(aIPCResponse->headers(),
-                             aIPCResponse->headersGuard());
-
-  nsCOMPtr<nsIInputStream> body;
-  int64_t bodySize;
-  GetUnfilteredBody(getter_AddRefs(body), &bodySize);
-
-  if (body) {
-    aAutoBodyStream.reset(
-        new mozilla::ipc::AutoIPCStream(aIPCResponse->body()));
-    DebugOnly<bool> ok = aAutoBodyStream->Serialize(body, aManager);
-    MOZ_ASSERT(ok);
-  }
-
-  aIPCResponse->bodySize() = bodySize;
-  aIPCResponse->errorCode() = mErrorCode;
-  aIPCResponse->alternativeDataType() = GetAlternativeDataType();
-
-  nsCOMPtr<nsIInputStream> alternativeBody = TakeAlternativeBody();
-  if (alternativeBody) {
-    aAutoAlternativeBodyStream.reset(
-        new mozilla::ipc::AutoIPCStream(aIPCResponse->alternativeBody()));
-    DebugOnly<bool> ok =
-        aAutoAlternativeBodyStream->Serialize(alternativeBody, aManager);
-    MOZ_ASSERT(ok);
-  }
-
-  aIPCResponse->channelInfo() = mChannelInfo.AsIPCChannelInfo();
-
-  if (mPrincipalInfo) {
-    aIPCResponse->principalInfo().emplace(*mPrincipalInfo);
-  }
-}
-
 already_AddRefed<InternalResponse> InternalResponse::Clone(
     CloneType aCloneType) {
   RefPtr<InternalResponse> clone = CreateIncompleteCopy();
 
   clone->mHeaders = new InternalHeaders(*mHeaders);
 
   // Make sure the clone response will have the same padding size.
   clone->mPaddingInfo = mPaddingInfo;
--- a/dom/fetch/InternalResponse.h
+++ b/dom/fetch/InternalResponse.h
@@ -21,38 +21,28 @@
 namespace mozilla {
 namespace ipc {
 class PrincipalInfo;
 class AutoIPCStream;
 }  // namespace ipc
 
 namespace dom {
 
-class IPCInternalResponse;
 class InternalHeaders;
 
 class InternalResponse final {
   friend class FetchDriver;
 
  public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalResponse)
 
   InternalResponse(
       uint16_t aStatus, const nsACString& aStatusText,
       RequestCredentials aCredentialsMode = RequestCredentials::Omit);
 
-  static RefPtr<InternalResponse> FromIPC(
-      const IPCInternalResponse& aIPCResponse);
-
-  template <typename M>
-  void ToIPC(
-      IPCInternalResponse* aIPCResponse, M* aManager,
-      UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
-      UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
-
   enum CloneType {
     eCloneInputStream,
     eDontCloneInputStream,
   };
 
   already_AddRefed<InternalResponse> Clone(CloneType eCloneType);
 
   static already_AddRefed<InternalResponse> NetworkError(nsresult aRv) {
@@ -216,34 +206,16 @@ class InternalResponse final {
   uint32_t GetPaddingInfo();
 
   nsresult GeneratePaddingInfo();
 
   int64_t GetPaddingSize();
 
   void SetPaddingSize(int64_t aPaddingSize);
 
-  void SetAlternativeDataType(const nsACString& aAltDataType) {
-    if (mWrappedResponse) {
-      return mWrappedResponse->SetAlternativeDataType(aAltDataType);
-    }
-
-    MOZ_DIAGNOSTIC_ASSERT(mAlternativeDataType.IsEmpty());
-
-    mAlternativeDataType.Assign(aAltDataType);
-  }
-
-  const nsCString& GetAlternativeDataType() {
-    if (mWrappedResponse) {
-      return mWrappedResponse->GetAlternativeDataType();
-    }
-
-    return mAlternativeDataType;
-  }
-
   void SetAlternativeBody(nsIInputStream* aAlternativeBody) {
     if (mWrappedResponse) {
       return mWrappedResponse->SetAlternativeBody(aAlternativeBody);
     }
     // A request's body may not be reset once set.
     MOZ_DIAGNOSTIC_ASSERT(!mAlternativeBody);
 
     mAlternativeBody = aAlternativeBody;
@@ -346,17 +318,16 @@ class InternalResponse final {
   // It's used to passed to the CacheResponse to generate padding size. Once, we
   // generate the padding size for resposne, we don't need it anymore.
   Maybe<uint32_t> mPaddingInfo;
   int64_t mPaddingSize;
   nsresult mErrorCode;
   RequestCredentials mCredentialsMode;
 
   // For alternative data such as JS Bytecode cached in the HTTP cache.
-  nsCString mAlternativeDataType;
   nsCOMPtr<nsIInputStream> mAlternativeBody;
   nsMainThreadPtrHandle<nsICacheInfoChannel> mCacheInfoChannel;
 
  public:
   static const int64_t UNKNOWN_BODY_SIZE = -1;
   static const int64_t UNKNOWN_PADDING_SIZE = -1;
 
  private:
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1377,42 +1377,16 @@ NS_IMETHODIMP
 RemoteWindowContext::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
   nsCOMPtr<nsILoadContext> loadContext = mBrowserParent->GetLoadContext();
   *aUsePrivateBrowsing = loadContext && loadContext->UsePrivateBrowsing();
   return NS_OK;
 }
 
 }  // namespace
 
-void ContentParent::MaybeAsyncSendShutDownMessage() {
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!TryToRecycle());
-
-#ifdef DEBUG
-  // Calling this below while the lock is acquired will deadlock.
-  bool shouldKeepProcessAlive = ShouldKeepProcessAlive();
-#endif
-
-  auto lock = mRemoteWorkerActorData.Lock();
-  MOZ_ASSERT_IF(!lock->mCount, !shouldKeepProcessAlive);
-
-  if (lock->mCount) {
-    return;
-  }
-
-  MOZ_ASSERT(!lock->mShutdownStarted);
-  lock->mShutdownStarted = true;
-
-  // In the case of normal shutdown, send a shutdown message to child to
-  // allow it to perform shutdown tasks.
-  MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
-      "dom::ContentParent::ShutDownProcess", this,
-      &ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
-}
-
 void ContentParent::ShutDownProcess(ShutDownMethod aMethod) {
   if (mScriptableHelper) {
     static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
     mScriptableHelper = nullptr;
   }
 
   // Shutting down by sending a shutdown message works differently than the
   // other methods. We first call Shutdown() in the child. After the child is
@@ -1747,27 +1721,24 @@ bool ContentParent::TryToRecycle() {
   }
 
   // The PreallocatedProcessManager took over the ownership let's not keep a
   // reference to it, until we don't take it back.
   RemoveFromList();
   return true;
 }
 
-bool ContentParent::ShouldKeepProcessAlive() {
+bool ContentParent::ShouldKeepProcessAlive() const {
   if (IsForJSPlugin()) {
     return true;
   }
 
   // If we have active workers, we need to stay alive.
-  {
-    const auto lock = mRemoteWorkerActorData.Lock();
-    if (lock->mCount) {
-      return true;
-    }
+  if (mRemoteWorkerActors) {
+    return true;
   }
 
   if (!sBrowserContentParents) {
     return false;
   }
 
   // If we have already been marked as dead, don't prevent shutdown.
   if (!IsAlive()) {
@@ -1869,17 +1840,21 @@ void ContentParent::NotifyTabDestroyed(c
         permissionRequestParent);
   }
 
   // There can be more than one PBrowser for a given app process
   // because of popup windows.  When the last one closes, shut
   // us down.
   if (ManagedPBrowserParent().Count() == 1 && !ShouldKeepProcessAlive() &&
       !TryToRecycle()) {
-    MaybeAsyncSendShutDownMessage();
+    // In the case of normal shutdown, send a shutdown message to child to
+    // allow it to perform shutdown tasks.
+    MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
+        "dom::ContentParent::ShutDownProcess", this,
+        &ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
   }
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvOpenRecordReplayChannel(
     const uint32_t& aChannelId, FileDescriptor* aConnection) {
   // We should only get this message from the child if it is recording or
   // replaying.
   if (!this->IsRecordingOrReplaying()) {
@@ -2294,17 +2269,17 @@ ContentParent::ContentParent(ContentPare
       mLaunchTS(TimeStamp::Now()),
       mLaunchYieldTS(mLaunchTS),
       mActivateTS(mLaunchTS),
       mOpener(aOpener),
       mRemoteType(aRemoteType),
       mChildID(gContentChildID++),
       mGeolocationWatchID(-1),
       mJSPluginID(aJSPluginID),
-      mRemoteWorkerActorData("ContentParent::mRemoteWorkerActorData"),
+      mRemoteWorkerActors(0),
       mNumDestroyingTabs(0),
       mLifecycleState(LifecycleState::LAUNCHING),
       mIsForBrowser(!mRemoteType.IsEmpty()),
       mRecordReplayState(aRecordReplayState),
       mRecordingFile(aRecordingFile),
       mCalledClose(false),
       mCalledKillHard(false),
       mCreatedPairedMinidumps(false),
@@ -5936,35 +5911,33 @@ mozilla::ipc::IPCResult ContentParent::R
 
   aContext->Group()->EachOtherParent(this, [&](ContentParent* aParent) {
     Unused << aParent->SendRestoreBrowsingContextChildren(aContext, aChildren);
   });
 
   return IPC_OK();
 }
 
-void ContentParent::RegisterRemoteWorkerActor() {
-  auto lock = mRemoteWorkerActorData.Lock();
-  ++lock->mCount;
-}
+void ContentParent::RegisterRemoteWorkerActor() { ++mRemoteWorkerActors; }
 
 void ContentParent::UnregisterRemoveWorkerActor() {
   MOZ_ASSERT(NS_IsMainThread());
 
-  {
-    auto lock = mRemoteWorkerActorData.Lock();
-    if (--lock->mCount) {
-      return;
-    }
+  if (--mRemoteWorkerActors) {
+    return;
   }
 
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
   if (!cpm->GetBrowserParentCountByProcessId(ChildID()) &&
       !ShouldKeepProcessAlive() && !TryToRecycle()) {
-    MaybeAsyncSendShutDownMessage();
+    // In the case of normal shutdown, send a shutdown message to child to
+    // allow it to perform shutdown tasks.
+    MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
+        "dom::ContentParent::ShutDownProcess", this,
+        &ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
   }
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvWindowClose(
     BrowsingContext* aContext, bool aTrustedCaller) {
   if (!aContext || aContext->IsDiscarded()) {
     MOZ_LOG(
         BrowsingContext::GetLog(), LogLevel::Debug,
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -13,17 +13,16 @@
 #include "mozilla/dom/RemoteBrowser.h"
 #include "mozilla/gfx/gfxVarReceiver.h"
 #include "mozilla/gfx/GPUProcessListener.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/PParentToChildStreamParent.h"
 #include "mozilla/ipc/PChildToParentStreamParent.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/DataMutex.h"
 #include "mozilla/FileUtils.h"
 #include "mozilla/HalTypes.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/MemoryReportingProcess.h"
 #include "mozilla/MozPromise.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Variant.h"
@@ -110,17 +109,16 @@ namespace dom {
 class BrowsingContextGroup;
 class Element;
 class BrowserParent;
 class ClonedMessageData;
 class MemoryReport;
 class TabContext;
 class GetFilesHelper;
 class MemoryReportRequestHost;
-class RemoteWorkerManager;
 struct CancelContentJSOptions;
 
 #define NS_CONTENTPARENT_IID                         \
   {                                                  \
     0xeeec9ebf, 0x8ecf, 0x4e38, {                    \
       0x81, 0xda, 0xb7, 0x34, 0x13, 0x7e, 0xac, 0xf3 \
     }                                                \
   }
@@ -142,17 +140,16 @@ class ContentParent final : public PCont
   typedef mozilla::ipc::TestShellParent TestShellParent;
   typedef mozilla::ipc::URIParams URIParams;
   typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
   typedef mozilla::dom::ClonedMessageData ClonedMessageData;
   typedef mozilla::dom::BrowsingContextGroup BrowsingContextGroup;
 
   friend class mozilla::PreallocatedProcessManagerImpl;
   friend class PContentParent;
-  friend class mozilla::dom::RemoteWorkerManager;
 #ifdef FUZZING
   friend class mozilla::ipc::ProtocolFuzzerHelper;
 #endif
 
  public:
   using LaunchError = mozilla::ipc::LaunchError;
   using LaunchPromise =
       mozilla::MozPromise<RefPtr<ContentParent>, LaunchError, false>;
@@ -746,17 +743,17 @@ class ContentParent final : public PCont
    * GetNewOrUsedBrowserProcess.
    */
   void RemoveFromList();
 
   /**
    * Decide whether the process should be kept alive even when it would normally
    * be shut down, for example when all its tabs are closed.
    */
-  bool ShouldKeepProcessAlive();
+  bool ShouldKeepProcessAlive() const;
 
   /**
    * Mark this ContentParent as "troubled". This means that it is still alive,
    * but it won't be returned for new tabs in GetNewOrUsedBrowserProcess.
    */
   void MarkAsTroubled();
 
   /**
@@ -772,18 +769,16 @@ class ContentParent final : public PCont
     // Send a shutdown message and wait for FinishShutdown call back.
     SEND_SHUTDOWN_MESSAGE,
     // Close the channel ourselves and let the subprocess clean up itself.
     CLOSE_CHANNEL,
     // Close the channel with error and let the subprocess clean up itself.
     CLOSE_CHANNEL_WITH_ERROR,
   };
 
-  void MaybeAsyncSendShutDownMessage();
-
   /**
    * Exit the subprocess and vamoose.  After this call IsAlive()
    * will return false and this ContentParent will not be returned
    * by the Get*() funtions.  However, the shutdown sequence itself
    * may be asynchronous.
    *
    * If aMethod is CLOSE_CHANNEL_WITH_ERROR and this is the first call
    * to ShutDownProcess, then we'll close our channel using CloseWithError()
@@ -1240,34 +1235,21 @@ class ContentParent final : public PCont
   int32_t mJSPluginID;
 
   // After we initiate shutdown, we also start a timer to ensure
   // that even content processes that are 100% blocked (say from
   // SIGSTOP), are still killed eventually.  This task enforces that
   // timer.
   nsCOMPtr<nsITimer> mForceKillTimer;
 
-  // `mCount` is increased when a RemoteWorkerParent actor is created for this
-  // ContentProcess and it is decreased when the actor is destroyed.
-  //
-  // `mShutdownStarted` is flipped to `true` when a runnable that calls
-  // `ShutDownProcess` is dispatched; it's needed because the corresponding
-  // Content Process may be shutdown if there's no remote worker actors, and
-  // decrementing `mCount` and the call to `ShutDownProcess` are async. So,
-  // when a worker is going to be spawned and we see that `mCount` is 0,
-  // we can decide whether or not to use that process based on the value of
-  // `mShutdownStarted.`
-  //
+  // Number of active remote workers. This value is increased when a
+  // RemoteWorkerParent actor is created for this ContentProcess and it is
+  // decreased when the actor is destroyed.
   // It's touched on PBackground thread and on main-thread.
-  struct RemoteWorkerActorData {
-    uint32_t mCount = 0;
-    bool mShutdownStarted = false;
-  };
-
-  DataMutex<RemoteWorkerActorData> mRemoteWorkerActorData;
+  Atomic<uint32_t> mRemoteWorkerActors;
 
   // How many tabs we're waiting to finish their destruction
   // sequence.  Precisely, how many BrowserParents have called
   // NotifyTabDestroying() but not called NotifyTabDestroyed().
   int32_t mNumDestroyingTabs;
 
   // The process starts in the LAUNCHING state, and transitions to
   // ALIVE once it can accept IPC messages.  It remains ALIVE only
--- a/dom/ipc/URLClassifierParent.h
+++ b/dom/ipc/URLClassifierParent.h
@@ -11,18 +11,16 @@
 #include "mozilla/dom/PURLClassifierParent.h"
 #include "mozilla/dom/PURLClassifierLocalParent.h"
 #include "nsIURIClassifier.h"
 #include "nsIUrlClassifierFeature.h"
 
 namespace mozilla {
 namespace dom {
 
-class IPCURLClassifierFeature;
-
 //////////////////////////////////////////////////////////////
 // URLClassifierParent
 
 class URLClassifierParent : public nsIURIClassifierCallback,
                             public PURLClassifierParent {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
--- a/dom/media/webrtc/PMediaTransport.ipdl
+++ b/dom/media/webrtc/PMediaTransport.ipdl
@@ -18,17 +18,16 @@ using struct mozilla::dom::RTCStatsRepor
 using struct mozilla::dom::MovableRTCStatsReportInternal from "mozilla/media/webrtc/WebrtcGlobal.h";
 using WebrtcGlobalLog from "mozilla/media/webrtc/WebrtcGlobal.h";
 using mozilla::dom::RTCIceServer from "mozilla/dom/RTCConfigurationBinding.h";
 using mozilla::dom::RTCIceTransportPolicy from "mozilla/dom/RTCConfigurationBinding.h";
 using TabId from "mozilla/dom/ipc/IdType.h";
 
 // ParamTraits stuff for our own classes
 using MediaPacket from "mtransport/mediapacket.h";
-include "mozilla/net/NrIceStunAddrMessageUtils.h";
 using net::NrIceStunAddrArray from "mozilla/net/PStunAddrsParams.h";
 #endif // MOZ_WEBRTC
 
 namespace mozilla {
 namespace dom {
 
 async protocol PMediaTransport {
   manager PBackground;
--- a/dom/notification/Notification.cpp
+++ b/dom/notification/Notification.cpp
@@ -22,17 +22,16 @@
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/NotificationEvent.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseWorkerProxy.h"
 #include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
 #include "mozilla/dom/ServiceWorkerManager.h"
-#include "mozilla/dom/ServiceWorkerUtils.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/dom/WorkerScope.h"
 
 #include "nsAlertsUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentPermissionHelper.h"
 #include "nsContentUtils.h"
--- a/dom/performance/moz.build
+++ b/dom/performance/moz.build
@@ -37,13 +37,11 @@ UNIFIED_SOURCES += [
     'PerformanceResourceTiming.cpp',
     'PerformanceServerTiming.cpp',
     'PerformanceService.cpp',
     'PerformanceStorageWorker.cpp',
     'PerformanceTiming.cpp',
     'PerformanceWorker.cpp',
 ]
 
-include('/ipc/chromium/chromium-config.mozbuild')
-
 MOCHITEST_MANIFESTS += [ 'tests/mochitest.ini' ]
 
 FINAL_LIBRARY = 'xul'
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpChild.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "FetchEventOpChild.h"
-
-#include <utility>
-
-#include "MainThreadUtils.h"
-#include "nsContentPolicyUtils.h"
-#include "nsContentUtils.h"
-#include "nsDebug.h"
-#include "nsError.h"
-#include "nsIChannel.h"
-#include "nsIConsoleReportCollector.h"
-#include "nsIContentPolicy.h"
-#include "nsIInputStream.h"
-#include "nsILoadInfo.h"
-#include "nsINetworkInterceptController.h"
-#include "nsIObserverService.h"
-#include "nsIScriptError.h"
-#include "nsISupportsImpl.h"
-#include "nsIURI.h"
-#include "nsNetUtil.h"
-#include "nsProxyRelease.h"
-#include "nsTArray.h"
-#include "nsThreadUtils.h"
-
-#include "ServiceWorkerPrivate.h"
-#include "mozilla/Assertions.h"
-#include "mozilla/LoadInfo.h"
-#include "mozilla/Services.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/InternalHeaders.h"
-#include "mozilla/dom/InternalResponse.h"
-#include "mozilla/dom/PRemoteWorkerControllerChild.h"
-#include "mozilla/dom/ServiceWorkerRegistrationInfo.h"
-#include "mozilla/net/NeckoChannelParams.h"
-
-namespace mozilla {
-namespace dom {
-
-namespace {
-
-bool CSPPermitsResponse(nsILoadInfo* aLoadInfo, InternalResponse* aResponse,
-                        const nsACString& aWorkerScriptSpec) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aLoadInfo);
-
-  nsCString url = aResponse->GetUnfilteredURL();
-  if (url.IsEmpty()) {
-    // Synthetic response.
-    url = aWorkerScriptSpec;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, nullptr);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  int16_t decision = nsIContentPolicy::ACCEPT;
-  rv = NS_CheckContentLoadPolicy(uri, aLoadInfo, EmptyCString(), &decision);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  return decision == nsIContentPolicy::ACCEPT;
-}
-
-void AsyncLog(nsIInterceptedChannel* aChannel, const nsACString& aScriptSpec,
-              uint32_t aLineNumber, uint32_t aColumnNumber,
-              const nsACString& aMessageName, nsTArray<nsString>&& aParams) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aChannel);
-
-  nsCOMPtr<nsIConsoleReportCollector> reporter =
-      aChannel->GetConsoleReportCollector();
-
-  if (reporter) {
-    // NOTE: is appears that `const nsTArray<nsString>&` is required for
-    // nsIConsoleReportCollector::AddConsoleReport to resolve to the correct
-    // overload.
-    const nsTArray<nsString> params = std::move(aParams);
-
-    reporter->AddConsoleReport(
-        nsIScriptError::errorFlag,
-        NS_LITERAL_CSTRING("Service Worker Interception"),
-        nsContentUtils::eDOM_PROPERTIES, aScriptSpec, aLineNumber,
-        aColumnNumber, aMessageName, params);
-  }
-}
-
-class SynthesizeResponseWatcher final : public nsIInterceptedBodyCallback {
- public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-
-  SynthesizeResponseWatcher(
-      const nsMainThreadPtrHandle<nsIInterceptedChannel>& aInterceptedChannel,
-      const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
-      const bool aIsNonSubresourceRequest,
-      FetchEventRespondWithClosure&& aClosure, nsAString&& aRequestURL)
-      : mInterceptedChannel(aInterceptedChannel),
-        mRegistration(aRegistration),
-        mIsNonSubresourceRequest(aIsNonSubresourceRequest),
-        mClosure(std::move(aClosure)),
-        mRequestURL(std::move(aRequestURL)) {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(mInterceptedChannel);
-    MOZ_ASSERT(mRegistration);
-  }
-
-  NS_IMETHOD
-  BodyComplete(nsresult aRv) override {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(mInterceptedChannel);
-
-    if (NS_WARN_IF(NS_FAILED(aRv))) {
-      AsyncLog(mInterceptedChannel, mClosure.respondWithScriptSpec(),
-               mClosure.respondWithLineNumber(),
-               mClosure.respondWithColumnNumber(),
-               NS_LITERAL_CSTRING("InterceptionFailedWithURL"), {mRequestURL});
-
-      CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
-
-      return NS_OK;
-    }
-
-    nsresult rv = mInterceptedChannel->FinishSynthesizedResponse();
-
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      CancelInterception(rv);
-    }
-
-    mInterceptedChannel = nullptr;
-
-    return NS_OK;
-  }
-
-  // See FetchEventOpChild::MaybeScheduleRegistrationUpdate() for comments.
-  void CancelInterception(nsresult aStatus) {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(mInterceptedChannel);
-    MOZ_ASSERT(mRegistration);
-
-    mInterceptedChannel->CancelInterception(aStatus);
-
-    if (mIsNonSubresourceRequest) {
-      mRegistration->MaybeScheduleUpdate();
-    } else {
-      mRegistration->MaybeScheduleTimeCheckAndUpdate();
-    }
-
-    mInterceptedChannel = nullptr;
-    mRegistration = nullptr;
-  }
-
- private:
-  ~SynthesizeResponseWatcher() {
-    if (NS_WARN_IF(mInterceptedChannel)) {
-      CancelInterception(NS_ERROR_DOM_ABORT_ERR);
-    }
-  }
-
-  nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
-  nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
-  const bool mIsNonSubresourceRequest;
-  const FetchEventRespondWithClosure mClosure;
-  const nsString mRequestURL;
-};
-
-NS_IMPL_ISUPPORTS(SynthesizeResponseWatcher, nsIInterceptedBodyCallback)
-
-}  // anonymous namespace
-
-/* static */ RefPtr<GenericPromise> FetchEventOpChild::Create(
-    PRemoteWorkerControllerChild* aManager,
-    ServiceWorkerFetchEventOpArgs&& aArgs,
-    nsCOMPtr<nsIInterceptedChannel> aInterceptedChannel,
-    RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
-    RefPtr<KeepAliveToken>&& aKeepAliveToken) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aManager);
-  MOZ_ASSERT(aInterceptedChannel);
-  MOZ_ASSERT(aKeepAliveToken);
-
-  FetchEventOpChild* actor = new FetchEventOpChild(
-      std::move(aArgs), std::move(aInterceptedChannel),
-      std::move(aRegistration), std::move(aKeepAliveToken));
-  Unused << aManager->SendPFetchEventOpConstructor(actor, actor->mArgs);
-  return actor->mPromiseHolder.Ensure(__func__);
-}
-
-FetchEventOpChild::~FetchEventOpChild() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mInterceptedChannelHandled);
-  MOZ_DIAGNOSTIC_ASSERT(mPromiseHolder.IsEmpty());
-}
-
-FetchEventOpChild::FetchEventOpChild(
-    ServiceWorkerFetchEventOpArgs&& aArgs,
-    nsCOMPtr<nsIInterceptedChannel>&& aInterceptedChannel,
-    RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-    RefPtr<KeepAliveToken>&& aKeepAliveToken)
-    : mArgs(std::move(aArgs)),
-      mInterceptedChannel(std::move(aInterceptedChannel)),
-      mRegistration(std::move(aRegistration)),
-      mKeepAliveToken(std::move(aKeepAliveToken)) {}
-
-mozilla::ipc::IPCResult FetchEventOpChild::RecvAsyncLog(
-    const nsCString& aScriptSpec, const uint32_t& aLineNumber,
-    const uint32_t& aColumnNumber, const nsCString& aMessageName,
-    nsTArray<nsString>&& aParams) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mInterceptedChannel);
-
-  AsyncLog(mInterceptedChannel, aScriptSpec, aLineNumber, aColumnNumber,
-           aMessageName, std::move(aParams));
-
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult FetchEventOpChild::RecvRespondWith(
-    IPCFetchEventRespondWithResult&& aResult) {
-  AssertIsOnMainThread();
-
-  switch (aResult.type()) {
-    case IPCFetchEventRespondWithResult::TIPCSynthesizeResponseArgs:
-      SynthesizeResponse(std::move(aResult.get_IPCSynthesizeResponseArgs()));
-      break;
-    case IPCFetchEventRespondWithResult::TResetInterceptionArgs:
-      ResetInterception();
-      break;
-    case IPCFetchEventRespondWithResult::TCancelInterceptionArgs:
-      CancelInterception(aResult.get_CancelInterceptionArgs().status());
-      break;
-    default:
-      MOZ_CRASH("Unknown IPCFetchEventRespondWithResult type!");
-      break;
-  }
-
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult FetchEventOpChild::Recv__delete__(
-    const ServiceWorkerFetchEventOpResult& aResult) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mRegistration);
-
-  if (NS_WARN_IF(!mInterceptedChannelHandled)) {
-    MOZ_ASSERT(NS_FAILED(aResult.rv()));
-    NS_WARNING(
-        "Failed to handle intercepted network request; canceling "
-        "interception!");
-
-    CancelInterception(aResult.rv());
-  }
-
-  mPromiseHolder.ResolveIfExists(true, __func__);
-
-  /**
-   * This corresponds to the "Fire Functional Event" algorithm's step 9:
-   *
-   * "If the time difference in seconds calculated by the current time minus
-   * registration's last update check time is greater than 84600, invoke Soft
-   * Update algorithm with registration."
-   *
-   * TODO: this is probably being called later than it should be; it should be
-   * called ASAP after dispatching the FetchEvent.
-   */
-  mRegistration->MaybeScheduleTimeCheckAndUpdate();
-
-  return IPC_OK();
-}
-
-void FetchEventOpChild::ActorDestroy(ActorDestroyReason) {
-  AssertIsOnMainThread();
-
-  // If `Recv__delete__` was called, it would have resolved the promise already.
-  mPromiseHolder.RejectIfExists(NS_ERROR_DOM_ABORT_ERR, __func__);
-
-  if (NS_WARN_IF(!mInterceptedChannelHandled)) {
-    Unused << Recv__delete__(NS_ERROR_DOM_ABORT_ERR);
-  }
-}
-
-nsresult FetchEventOpChild::StartSynthesizedResponse(
-    IPCSynthesizeResponseArgs&& aArgs) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mInterceptedChannel);
-  MOZ_ASSERT(!mInterceptedChannelHandled);
-  MOZ_ASSERT(mRegistration);
-
-  /**
-   * TODO: moving the IPCInternalResponse won't do anything right now because
-   * there isn't a prefect-forwarding or rvalue-ref-parameter overload of
-   * `InternalResponse::FromIPC().`
-   */
-  RefPtr<InternalResponse> response =
-      InternalResponse::FromIPC(aArgs.internalResponse());
-  if (NS_WARN_IF(!response)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsIChannel> underlyingChannel;
-  nsresult rv =
-      mInterceptedChannel->GetChannel(getter_AddRefs(underlyingChannel));
-  if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!underlyingChannel)) {
-    return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
-  }
-
-  nsCOMPtr<nsILoadInfo> loadInfo = underlyingChannel->LoadInfo();
-  if (!CSPPermitsResponse(loadInfo, response, mArgs.workerScriptSpec())) {
-    return NS_ERROR_CONTENT_BLOCKED;
-  }
-
-  MOZ_ASSERT(response->GetChannelInfo().IsInitialized());
-  ChannelInfo channelInfo = response->GetChannelInfo();
-  rv = mInterceptedChannel->SetChannelInfo(&channelInfo);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return NS_ERROR_INTERCEPTION_FAILED;
-  }
-
-  rv = mInterceptedChannel->SynthesizeStatus(
-      response->GetUnfilteredStatus(), response->GetUnfilteredStatusText());
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  AutoTArray<InternalHeaders::Entry, 5> entries;
-  response->UnfilteredHeaders()->GetEntries(entries);
-  for (auto& entry : entries) {
-    mInterceptedChannel->SynthesizeHeader(entry.mName, entry.mValue);
-  }
-
-  auto castLoadInfo = static_cast<mozilla::net::LoadInfo*>(loadInfo.get());
-  castLoadInfo->SynthesizeServiceWorkerTainting(response->GetTainting());
-
-  // Get the preferred alternative data type of the outer channel
-  nsAutoCString preferredAltDataType(EmptyCString());
-  nsCOMPtr<nsICacheInfoChannel> outerChannel =
-      do_QueryInterface(underlyingChannel);
-  if (outerChannel &&
-      !outerChannel->PreferredAlternativeDataTypes().IsEmpty()) {
-    preferredAltDataType.Assign(
-        outerChannel->PreferredAlternativeDataTypes()[0].type());
-  }
-
-  nsCOMPtr<nsIInputStream> body;
-  if (preferredAltDataType.Equals(response->GetAlternativeDataType())) {
-    body = response->TakeAlternativeBody();
-  }
-  if (!body) {
-    response->GetUnfilteredBody(getter_AddRefs(body));
-  } else {
-    Telemetry::ScalarAdd(Telemetry::ScalarID::SW_ALTERNATIVE_BODY_USED_COUNT,
-                         1);
-  }
-
-  // Propagate the URL to the content if the request mode is not "navigate".
-  // Note that, we only reflect the final URL if the response.redirected is
-  // false. We propagate all the URLs if the response.redirected is true.
-  const IPCInternalRequest& request = mArgs.internalRequest();
-  nsAutoCString responseURL;
-  if (request.requestMode() != RequestMode::Navigate) {
-    responseURL = response->GetUnfilteredURL();
-
-    // Similar to how we apply the request fragment to redirects automatically
-    // we also want to apply it automatically when propagating the response
-    // URL from a service worker interception.  Currently response.url strips
-    // the fragment, so this will never conflict with an existing fragment
-    // on the response.  In the future we will have to check for a response
-    // fragment and avoid overriding in that case.
-    if (!request.fragment().IsEmpty() && !responseURL.IsEmpty()) {
-      MOZ_ASSERT(!responseURL.Contains('#'));
-      responseURL.AppendLiteral("#");
-      responseURL.Append(request.fragment());
-    }
-  }
-
-  nsMainThreadPtrHandle<nsIInterceptedChannel> interceptedChannel(
-      new nsMainThreadPtrHolder<nsIInterceptedChannel>(
-          "nsIInterceptedChannel", mInterceptedChannel, false));
-
-  nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> registration(
-      new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(
-          "ServiceWorkerRegistrationInfo", mRegistration, false));
-
-  nsCString requestURL = request.urlList().LastElement();
-  if (!request.fragment().IsEmpty()) {
-    requestURL.AppendLiteral("#");
-    requestURL.Append(request.fragment());
-  }
-
-  RefPtr<SynthesizeResponseWatcher> watcher = new SynthesizeResponseWatcher(
-      interceptedChannel, registration, mArgs.isNonSubresourceRequest(),
-      std::move(aArgs.closure()), NS_ConvertUTF8toUTF16(responseURL));
-
-  rv = mInterceptedChannel->StartSynthesizedResponse(
-      body, watcher, nullptr /* TODO */, responseURL, response->IsRedirected());
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
-  if (obsService) {
-    obsService->NotifyObservers(underlyingChannel,
-                                "service-worker-synthesized-response", nullptr);
-  }
-
-  return rv;
-}
-
-void FetchEventOpChild::SynthesizeResponse(IPCSynthesizeResponseArgs&& aArgs) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mInterceptedChannel);
-  MOZ_ASSERT(!mInterceptedChannelHandled);
-
-  nsresult rv = StartSynthesizedResponse(std::move(aArgs));
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    NS_WARNING("Failed to synthesize response!");
-
-    mInterceptedChannel->CancelInterception(rv);
-  }
-
-  mInterceptedChannelHandled = true;
-
-  MaybeScheduleRegistrationUpdate();
-}
-
-void FetchEventOpChild::ResetInterception() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mInterceptedChannel);
-  MOZ_ASSERT(!mInterceptedChannelHandled);
-
-  nsresult rv = mInterceptedChannel->ResetInterception();
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    NS_WARNING("Failed to resume intercepted network request!");
-
-    mInterceptedChannel->CancelInterception(rv);
-  }
-
-  mInterceptedChannelHandled = true;
-
-  MaybeScheduleRegistrationUpdate();
-}
-
-void FetchEventOpChild::CancelInterception(nsresult aStatus) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mInterceptedChannel);
-  MOZ_ASSERT(!mInterceptedChannelHandled);
-  MOZ_ASSERT(NS_FAILED(aStatus));
-
-  mInterceptedChannel->CancelInterception(aStatus);
-  mInterceptedChannelHandled = true;
-
-  MaybeScheduleRegistrationUpdate();
-}
-
-/**
- * This corresponds to the "Handle Fetch" algorithm's steps 20.3, 21.2, and
- * 22.2:
- *
- * "If request is a non-subresource request, or request is a subresource
- * request and the time difference in seconds calculated by the current time
- * minus registration's last update check time is greater than 86400, invoke
- * Soft Update algorithm with registration."
- */
-void FetchEventOpChild::MaybeScheduleRegistrationUpdate() const {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mRegistration);
-  MOZ_ASSERT(mInterceptedChannelHandled);
-
-  if (mArgs.isNonSubresourceRequest()) {
-    mRegistration->MaybeScheduleUpdate();
-  } else {
-    mRegistration->MaybeScheduleTimeCheckAndUpdate();
-  }
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpChild.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_fetcheventopchild_h__
-#define mozilla_dom_fetcheventopchild_h__
-
-#include "nsCOMPtr.h"
-
-#include "mozilla/MozPromise.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/dom/PFetchEventOpChild.h"
-#include "mozilla/dom/ServiceWorkerOpArgs.h"
-
-class nsIInterceptedChannel;
-
-namespace mozilla {
-namespace dom {
-
-class KeepAliveToken;
-class PRemoteWorkerControllerChild;
-class ServiceWorkerRegistrationInfo;
-
-/**
- * FetchEventOpChild represents an in-flight FetchEvent operation.
- */
-class FetchEventOpChild final : public PFetchEventOpChild {
-  friend class PFetchEventOpChild;
-
- public:
-  static RefPtr<GenericPromise> Create(
-      PRemoteWorkerControllerChild* aManager,
-      ServiceWorkerFetchEventOpArgs&& aArgs,
-      nsCOMPtr<nsIInterceptedChannel> aInterceptedChannel,
-      RefPtr<ServiceWorkerRegistrationInfo> aRegistrationInfo,
-      RefPtr<KeepAliveToken>&& aKeepAliveToken);
-
-  ~FetchEventOpChild();
-
- private:
-  FetchEventOpChild(ServiceWorkerFetchEventOpArgs&& aArgs,
-                    nsCOMPtr<nsIInterceptedChannel>&& aInterceptedChannel,
-                    RefPtr<ServiceWorkerRegistrationInfo>&& aRegistrationInfo,
-                    RefPtr<KeepAliveToken>&& aKeepAliveToken);
-
-  mozilla::ipc::IPCResult RecvAsyncLog(const nsCString& aScriptSpec,
-                                       const uint32_t& aLineNumber,
-                                       const uint32_t& aColumnNumber,
-                                       const nsCString& aMessageName,
-                                       nsTArray<nsString>&& aParams);
-
-  mozilla::ipc::IPCResult RecvRespondWith(
-      IPCFetchEventRespondWithResult&& aResult);
-
-  mozilla::ipc::IPCResult Recv__delete__(
-      const ServiceWorkerFetchEventOpResult& aResult) override;
-
-  void ActorDestroy(ActorDestroyReason) override;
-
-  nsresult StartSynthesizedResponse(IPCSynthesizeResponseArgs&& aArgs);
-
-  void SynthesizeResponse(IPCSynthesizeResponseArgs&& aArgs);
-
-  void ResetInterception();
-
-  void CancelInterception(nsresult aStatus);
-
-  void MaybeScheduleRegistrationUpdate() const;
-
-  const ServiceWorkerFetchEventOpArgs mArgs;
-  nsCOMPtr<nsIInterceptedChannel> mInterceptedChannel;
-  RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
-  RefPtr<KeepAliveToken> mKeepAliveToken;
-  bool mInterceptedChannelHandled = false;
-  MozPromiseHolder<GenericPromise> mPromiseHolder;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_fetcheventopchild_h__
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpParent.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "FetchEventOpParent.h"
-
-#include "nsDebug.h"
-
-#include "mozilla/Assertions.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/FetchEventOpProxyParent.h"
-#include "mozilla/dom/RemoteWorkerControllerParent.h"
-#include "mozilla/dom/RemoteWorkerParent.h"
-#include "mozilla/ipc/BackgroundParent.h"
-
-namespace mozilla {
-
-using namespace ipc;
-
-namespace dom {
-
-void FetchEventOpParent::Initialize(
-    const ServiceWorkerFetchEventOpArgs& aArgs) {
-  AssertIsInMainProcess();
-  AssertIsOnBackgroundThread();
-
-  RemoteWorkerControllerParent* manager =
-      static_cast<RemoteWorkerControllerParent*>(Manager());
-  MOZ_ASSERT(manager);
-
-  // This will be null when the manager's RemoteWorkerController has shutdown.
-  RefPtr<RemoteWorkerParent> proxyManager = manager->GetRemoteWorkerParent();
-  if (NS_WARN_IF(!proxyManager)) {
-    Unused << Send__delete__(this, NS_ERROR_DOM_ABORT_ERR);
-
-    return;
-  }
-
-  FetchEventOpProxyParent::Create(proxyManager.get(), aArgs, this);
-}
-
-void FetchEventOpParent::ActorDestroy(ActorDestroyReason) {
-  AssertIsOnBackgroundThread();
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpParent.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_fetcheventopparent_h__
-#define mozilla_dom_fetcheventopparent_h__
-
-#include "nsISupports.h"
-
-#include "mozilla/dom/PFetchEventOpParent.h"
-
-namespace mozilla {
-namespace dom {
-
-class ServiceWorkerFetchEventOpArgs;
-
-class FetchEventOpParent final : public PFetchEventOpParent {
-  friend class PFetchEventOpParent;
-
- public:
-  NS_INLINE_DECL_REFCOUNTING(FetchEventOpParent)
-
-  FetchEventOpParent() = default;
-
-  void Initialize(const ServiceWorkerFetchEventOpArgs& aArgs);
-
- private:
-  ~FetchEventOpParent() = default;
-
-  void ActorDestroy(ActorDestroyReason) override;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_fetcheventopparent_h__
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpProxyChild.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "FetchEventOpProxyChild.h"
-
-#include <utility>
-
-#include "nsCOMPtr.h"
-#include "nsDebug.h"
-#include "nsThreadUtils.h"
-
-#include "mozilla/Assertions.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/RemoteWorkerChild.h"
-#include "mozilla/dom/RemoteWorkerService.h"
-#include "mozilla/dom/ServiceWorkerOp.h"
-#include "mozilla/dom/WorkerCommon.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "mozilla/ipc/IPCStreamUtils.h"
-
-namespace mozilla {
-
-using namespace ipc;
-
-namespace dom {
-
-namespace {
-
-nsresult GetIPCSynthesizeResponseArgs(
-    IPCSynthesizeResponseArgs* aIPCArgs, SynthesizeResponseArgs&& aArgs,
-    UniquePtr<AutoIPCStream>& aAutoBodyStream,
-    UniquePtr<AutoIPCStream>& aAutoAlternativeBodyStream) {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-
-  PBackgroundChild* bgChild = BackgroundChild::GetOrCreateForCurrentThread();
-
-  if (NS_WARN_IF(!bgChild)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  aArgs.first()->ToIPC(&aIPCArgs->internalResponse(), bgChild, aAutoBodyStream,
-                       aAutoAlternativeBodyStream);
-  aIPCArgs->closure() = std::move(aArgs.second());
-
-  return NS_OK;
-}
-
-}  // anonymous namespace
-
-void FetchEventOpProxyChild::Initialize(
-    const ServiceWorkerFetchEventOpArgs& aArgs) {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-  MOZ_ASSERT(!mOp);
-
-  mInternalRequest = new InternalRequest(aArgs.internalRequest());
-
-  RemoteWorkerChild* manager = static_cast<RemoteWorkerChild*>(Manager());
-  MOZ_ASSERT(manager);
-
-  RefPtr<FetchEventOpProxyChild> self = this;
-
-  auto callback = [self](const ServiceWorkerOpResult& aResult) {
-    if (!self->CanSend()) {
-      return;
-    }
-
-    if (NS_WARN_IF(aResult.type() == ServiceWorkerOpResult::Tnsresult)) {
-      Unused << self->Send__delete__(self, aResult.get_nsresult());
-      return;
-    }
-
-    MOZ_ASSERT(aResult.type() ==
-               ServiceWorkerOpResult::TServiceWorkerFetchEventOpResult);
-
-    Unused << self->Send__delete__(self, aResult);
-  };
-
-  RefPtr<FetchEventOp> op = ServiceWorkerOp::Create(aArgs, std::move(callback))
-                                .template downcast<FetchEventOp>();
-
-  MOZ_ASSERT(op);
-
-  op->SetActor(this);
-  mOp = op;
-
-  op->GetRespondWithPromise()
-      ->Then(GetCurrentThreadSerialEventTarget(), __func__,
-             [self = std::move(self)](
-                 FetchEventRespondWithPromise::ResolveOrRejectValue&& aResult) {
-               self->mRespondWithPromiseRequestHolder.Complete();
-
-               if (NS_WARN_IF(aResult.IsReject())) {
-                 MOZ_ASSERT(NS_FAILED(aResult.RejectValue()));
-
-                 Unused << self->SendRespondWith(
-                     CancelInterceptionArgs(aResult.RejectValue()));
-                 return;
-               }
-
-               auto& result = aResult.ResolveValue();
-
-               if (result.is<SynthesizeResponseArgs>()) {
-                 IPCSynthesizeResponseArgs ipcArgs;
-                 UniquePtr<AutoIPCStream> autoBodyStream =
-                     MakeUnique<AutoIPCStream>();
-                 UniquePtr<AutoIPCStream> autoAlternativeBodyStream =
-                     MakeUnique<AutoIPCStream>();
-                 nsresult rv = GetIPCSynthesizeResponseArgs(
-                     &ipcArgs, result.extract<SynthesizeResponseArgs>(),
-                     autoBodyStream, autoAlternativeBodyStream);
-
-                 if (NS_WARN_IF(NS_FAILED(rv))) {
-                   Unused << self->SendRespondWith(CancelInterceptionArgs(rv));
-                   return;
-                 }
-
-                 Unused << self->SendRespondWith(ipcArgs);
-                 autoBodyStream->TakeOptionalValue();
-                 autoAlternativeBodyStream->TakeOptionalValue();
-               } else if (result.is<ResetInterceptionArgs>()) {
-                 Unused << self->SendRespondWith(
-                     result.extract<ResetInterceptionArgs>());
-               } else {
-                 Unused << self->SendRespondWith(
-                     result.extract<CancelInterceptionArgs>());
-               }
-             })
-      ->Track(mRespondWithPromiseRequestHolder);
-
-  manager->MaybeStartOp(std::move(op));
-}
-
-RefPtr<InternalRequest> FetchEventOpProxyChild::ExtractInternalRequest() {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(mInternalRequest);
-
-  return RefPtr<InternalRequest>(std::move(mInternalRequest));
-}
-
-void FetchEventOpProxyChild::ActorDestroy(ActorDestroyReason) {
-  Unused << NS_WARN_IF(mRespondWithPromiseRequestHolder.Exists());
-  mRespondWithPromiseRequestHolder.DisconnectIfExists();
-
-  mOp->RevokeActor(this);
-  mOp = nullptr;
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpProxyChild.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_fetcheventopproxychild_h__
-#define mozilla_dom_fetcheventopproxychild_h__
-
-#include "nsISupportsImpl.h"
-
-#include "ServiceWorkerOp.h"
-#include "ServiceWorkerOpPromise.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/dom/InternalRequest.h"
-#include "mozilla/dom/PFetchEventOpProxyChild.h"
-
-namespace mozilla {
-namespace dom {
-
-class InternalRequest;
-class ServiceWorkerFetchEventOpArgs;
-
-class FetchEventOpProxyChild final : public PFetchEventOpProxyChild {
-  friend class PFetchEventOpProxyChild;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchEventOpProxyChild)
-
-  FetchEventOpProxyChild() = default;
-
-  void Initialize(const ServiceWorkerFetchEventOpArgs& aArgs);
-
-  // Must only be called once and on a worker thread.
-  RefPtr<InternalRequest> ExtractInternalRequest();
-
- private:
-  ~FetchEventOpProxyChild() = default;
-
-  void ActorDestroy(ActorDestroyReason) override;
-
-  MozPromiseRequestHolder<FetchEventRespondWithPromise>
-      mRespondWithPromiseRequestHolder;
-
-  RefPtr<FetchEventOp> mOp;
-
-  // Initialized on RemoteWorkerService::Thread, read on a worker thread.
-  RefPtr<InternalRequest> mInternalRequest;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_fetcheventopproxychild_h__
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpProxyParent.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "FetchEventOpProxyParent.h"
-
-#include <utility>
-
-#include "nsCOMPtr.h"
-#include "nsIInputStream.h"
-
-#include "mozilla/Assertions.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/FetchEventOpParent.h"
-#include "mozilla/ipc/BackgroundParent.h"
-#include "mozilla/ipc/IPCStreamUtils.h"
-
-namespace mozilla {
-
-using namespace ipc;
-
-namespace dom {
-
-namespace {
-
-void MaybeDeserializeAndReserialize(const Maybe<IPCStream>& aDeserialize,
-                                    Maybe<IPCStream>& aReserialize,
-                                    UniquePtr<AutoIPCStream>& aAutoStream,
-                                    PBackgroundParent* aManager) {
-  nsCOMPtr<nsIInputStream> maybeDeserialized =
-      DeserializeIPCStream(aDeserialize);
-
-  if (!maybeDeserialized) {
-    return;
-  }
-
-  aAutoStream.reset(new AutoIPCStream(aReserialize));
-  DebugOnly<bool> ok = aAutoStream->Serialize(maybeDeserialized, aManager);
-  MOZ_ASSERT(ok);
-}
-
-}  // anonymous namespace
-
-/* static */ void FetchEventOpProxyParent::Create(
-    PRemoteWorkerParent* aManager, const ServiceWorkerFetchEventOpArgs& aArgs,
-    RefPtr<FetchEventOpParent> aReal) {
-  AssertIsInMainProcess();
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(aManager);
-  MOZ_ASSERT(aReal);
-
-  FetchEventOpProxyParent* actor =
-      new FetchEventOpProxyParent(std::move(aReal));
-
-  if (aArgs.internalRequest().body().isNothing()) {
-    Unused << aManager->SendPFetchEventOpProxyConstructor(actor, aArgs);
-    return;
-  }
-
-  ServiceWorkerFetchEventOpArgs copyArgs = aArgs;
-  IPCInternalRequest& copyRequest = copyArgs.internalRequest();
-
-  PBackgroundParent* bgParent = aManager->Manager();
-  MOZ_ASSERT(bgParent);
-
-  UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
-  MaybeDeserializeAndReserialize(aArgs.internalRequest().body(),
-                                 copyRequest.body(), autoBodyStream, bgParent);
-
-  Unused << aManager->SendPFetchEventOpProxyConstructor(actor, copyArgs);
-  autoBodyStream->TakeOptionalValue();
-}
-
-FetchEventOpProxyParent::~FetchEventOpProxyParent() {
-  AssertIsOnBackgroundThread();
-}
-
-FetchEventOpProxyParent::FetchEventOpProxyParent(
-    RefPtr<FetchEventOpParent>&& aReal)
-    : mReal(std::move(aReal)) {}
-
-mozilla::ipc::IPCResult FetchEventOpProxyParent::RecvAsyncLog(
-    const nsCString& aScriptSpec, const uint32_t& aLineNumber,
-    const uint32_t& aColumnNumber, const nsCString& aMessageName,
-    nsTArray<nsString>&& aParams) {
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(mReal);
-
-  Unused << mReal->SendAsyncLog(aScriptSpec, aLineNumber, aColumnNumber,
-                                aMessageName, aParams);
-
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult FetchEventOpProxyParent::RecvRespondWith(
-    const IPCFetchEventRespondWithResult& aResult) {
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(mReal);
-
-  // IPCSynthesizeResponseArgs possibly contains an IPCStream. If so,
-  // deserialize it and reserialize it before forwarding it to the main thread.
-  if (aResult.type() ==
-      IPCFetchEventRespondWithResult::TIPCSynthesizeResponseArgs) {
-    const IPCSynthesizeResponseArgs& originalArgs =
-        aResult.get_IPCSynthesizeResponseArgs();
-    const IPCInternalResponse& originalResponse =
-        originalArgs.internalResponse();
-
-    // Do nothing if neither the body nor the alt. body can be deserialized.
-    if (!originalResponse.body() && !originalResponse.alternativeBody()) {
-      Unused << mReal->SendRespondWith(aResult);
-      return IPC_OK();
-    }
-
-    IPCSynthesizeResponseArgs copyArgs = originalArgs;
-    IPCInternalResponse& copyResponse = copyArgs.internalResponse();
-
-    PRemoteWorkerControllerParent* manager = mReal->Manager();
-    MOZ_ASSERT(manager);
-
-    PBackgroundParent* bgParent = manager->Manager();
-    MOZ_ASSERT(bgParent);
-
-    UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
-    UniquePtr<AutoIPCStream> autoAlternativeBodyStream =
-        MakeUnique<AutoIPCStream>();
-
-    MaybeDeserializeAndReserialize(originalResponse.body(), copyResponse.body(),
-                                   autoBodyStream, bgParent);
-    MaybeDeserializeAndReserialize(originalResponse.alternativeBody(),
-                                   copyResponse.alternativeBody(),
-                                   autoAlternativeBodyStream, bgParent);
-
-    Unused << mReal->SendRespondWith(copyArgs);
-
-    autoBodyStream->TakeOptionalValue();
-    autoAlternativeBodyStream->TakeOptionalValue();
-  } else {
-    Unused << mReal->SendRespondWith(aResult);
-  }
-
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult FetchEventOpProxyParent::Recv__delete__(
-    const ServiceWorkerFetchEventOpResult& aResult) {
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(mReal);
-
-  Unused << mReal->Send__delete__(mReal, aResult);
-  mReal = nullptr;
-
-  return IPC_OK();
-}
-
-void FetchEventOpProxyParent::ActorDestroy(ActorDestroyReason) {
-  AssertIsOnBackgroundThread();
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/FetchEventOpProxyParent.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_fetcheventopproxyparent_h__
-#define mozilla_dom_fetcheventopproxyparent_h__
-
-#include "mozilla/RefPtr.h"
-#include "mozilla/dom/PFetchEventOpProxyParent.h"
-
-namespace mozilla {
-namespace dom {
-
-class FetchEventOpParent;
-class PRemoteWorkerParent;
-class ServiceWorkerFetchEventOpArgs;
-
-/**
- * FetchEventOpProxyParent owns a FetchEventOpParent and is responsible for
- * calling PFetchEventOpParent::Send__delete__.
- */
-class FetchEventOpProxyParent final : public PFetchEventOpProxyParent {
-  friend class PFetchEventOpProxyParent;
-
- public:
-  static void Create(PRemoteWorkerParent* aManager,
-                     const ServiceWorkerFetchEventOpArgs& aArgs,
-                     RefPtr<FetchEventOpParent> aReal);
-
-  ~FetchEventOpProxyParent();
-
- private:
-  explicit FetchEventOpProxyParent(RefPtr<FetchEventOpParent>&& aReal);
-
-  mozilla::ipc::IPCResult RecvAsyncLog(const nsCString& aScriptSpec,
-                                       const uint32_t& aLineNumber,
-                                       const uint32_t& aColumnNumber,
-                                       const nsCString& aMessageName,
-                                       nsTArray<nsString>&& aParams);
-
-  mozilla::ipc::IPCResult RecvRespondWith(
-      const IPCFetchEventRespondWithResult& aResult);
-
-  mozilla::ipc::IPCResult Recv__delete__(
-      const ServiceWorkerFetchEventOpResult& aResult) override;
-
-  void ActorDestroy(ActorDestroyReason) override;
-
-  RefPtr<FetchEventOpParent> mReal;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_fetcheventopproxyparent_h__
deleted file mode 100644
--- a/dom/serviceworkers/PFetchEventOp.ipdl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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 PRemoteWorkerController;
-
-include ServiceWorkerOpArgs;
-
-namespace mozilla {
-namespace dom {
-
-protocol PFetchEventOp {
-  manager PRemoteWorkerController;
-
- child:
-  async AsyncLog(nsCString aScriptSpec, uint32_t aLineNumber,
-                 uint32_t aColumnNumber, nsCString aMessageName,
-                 nsString[] aParams);
-
-  async RespondWith(IPCFetchEventRespondWithResult aResult);
-
-  async __delete__(ServiceWorkerFetchEventOpResult aResult);
-};
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/PFetchEventOpProxy.ipdl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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 PRemoteWorker;
-
-include ServiceWorkerOpArgs;
-
-namespace mozilla {
-namespace dom {
-
-protocol PFetchEventOpProxy {
-  manager PRemoteWorker;
-
- parent:
-  async AsyncLog(nsCString aScriptSpec, uint32_t aLineNumber,
-                 uint32_t aColumnNumber, nsCString aMessageName,
-                 nsString[] aParams);
-
-  async RespondWith(IPCFetchEventRespondWithResult aResult);
-
-  async __delete__(ServiceWorkerFetchEventOpResult aResult);
-};
-
-}  // namespace dom
-}  // namespace mozilla
--- a/dom/serviceworkers/ServiceWorkerEvents.cpp
+++ b/dom/serviceworkers/ServiceWorkerEvents.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "ServiceWorkerEvents.h"
 
-#include <utility>
-
 #include "nsAutoPtr.h"
 #include "nsContentUtils.h"
 #include "nsIConsoleReportCollector.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIOutputStream.h"
 #include "nsIScriptError.h"
 #include "nsITimedChannel.h"
@@ -38,17 +36,16 @@
 #include "mozilla/dom/EventBinding.h"
 #include "mozilla/dom/FetchEventBinding.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/dom/PushEventBinding.h"
 #include "mozilla/dom/PushMessageDataBinding.h"
 #include "mozilla/dom/PushUtil.h"
 #include "mozilla/dom/Request.h"
-#include "mozilla/dom/ServiceWorkerOp.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/dom/Response.h"
 #include "mozilla/dom/WorkerScope.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/net/NeckoChannelParams.h"
 
 #include "js/Conversions.h"
 #include "js/TypeDecls.h"
@@ -134,24 +131,16 @@ void FetchEvent::PostInit(
     nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
     nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
     const nsACString& aScriptSpec) {
   mChannel = aChannel;
   mRegistration = aRegistration;
   mScriptSpec.Assign(aScriptSpec);
 }
 
-void FetchEvent::PostInit(const nsACString& aScriptSpec,
-                          RefPtr<FetchEventOp> aRespondWithHandler) {
-  MOZ_ASSERT(aRespondWithHandler);
-
-  mScriptSpec.Assign(aScriptSpec);
-  mRespondWithHandler = std::move(aRespondWithHandler);
-}
-
 /*static*/
 already_AddRefed<FetchEvent> FetchEvent::Constructor(
     const GlobalObject& aGlobal, const nsAString& aType,
     const FetchEventInit& aOptions, ErrorResult& aRv) {
   RefPtr<EventTarget> owner = do_QueryObject(aGlobal.GetAsSupports());
   MOZ_ASSERT(owner);
   RefPtr<FetchEvent> e = new FetchEvent(owner);
   bool trusted = e->Init(owner);
@@ -801,31 +790,21 @@ void FetchEvent::RespondWith(JSContext* 
 
   RefPtr<InternalRequest> ir = mRequest->GetInternalRequest();
 
   nsAutoCString requestURL;
   ir->GetURL(requestURL);
 
   StopImmediatePropagation();
   mWaitToRespond = true;
-
-  if (mChannel) {
-    RefPtr<RespondWithHandler> handler = new RespondWithHandler(
-        mChannel, mRegistration, mRequest->Mode(), ir->IsClientRequest(),
-        mRequest->Redirect(), mScriptSpec, NS_ConvertUTF8toUTF16(requestURL),
-        ir->GetFragment(), spec, line, column);
-
-    aArg.AppendNativeHandler(handler);
-  } else {
-    MOZ_ASSERT(mRespondWithHandler);
-
-    mRespondWithHandler->RespondWithCalledAt(spec, line, column);
-    aArg.AppendNativeHandler(mRespondWithHandler);
-    mRespondWithHandler = nullptr;
-  }
+  RefPtr<RespondWithHandler> handler = new RespondWithHandler(
+      mChannel, mRegistration, mRequest->Mode(), ir->IsClientRequest(),
+      mRequest->Redirect(), mScriptSpec, NS_ConvertUTF8toUTF16(requestURL),
+      ir->GetFragment(), spec, line, column);
+  aArg.AppendNativeHandler(handler);
 
   if (!WaitOnPromise(aArg)) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
   }
 }
 
 void FetchEvent::PreventDefault(JSContext* aCx, CallerType aCallerType) {
   MOZ_ASSERT(aCx);
@@ -854,26 +833,19 @@ void FetchEvent::ReportCanceled() {
   ir->GetURL(url);
 
   // The variadic template provided by StringArrayAppender requires exactly
   // an nsString.
   NS_ConvertUTF8toUTF16 requestURL(url);
   // nsString requestURL;
   // CopyUTF8toUTF16(url, requestURL);
 
-  if (mChannel) {
-    ::AsyncLog(mChannel.get(), mPreventDefaultScriptSpec,
-               mPreventDefaultLineNumber, mPreventDefaultColumnNumber,
-               NS_LITERAL_CSTRING("InterceptionCanceledWithURL"), requestURL);
-  } else {
-    mRespondWithHandler->ReportCanceled(mPreventDefaultScriptSpec,
-                                        mPreventDefaultLineNumber,
-                                        mPreventDefaultColumnNumber);
-    mRespondWithHandler = nullptr;
-  }
+  ::AsyncLog(mChannel.get(), mPreventDefaultScriptSpec,
+             mPreventDefaultLineNumber, mPreventDefaultColumnNumber,
+             NS_LITERAL_CSTRING("InterceptionCanceledWithURL"), requestURL);
 }
 
 namespace {
 
 class WaitUntilHandler final : public PromiseNativeHandler {
   WorkerPrivate* mWorkerPrivate;
   const nsCString mScope;
   nsCString mSourceSpec;
--- a/dom/serviceworkers/ServiceWorkerEvents.h
+++ b/dom/serviceworkers/ServiceWorkerEvents.h
@@ -21,17 +21,16 @@
 
 class nsIInterceptedChannel;
 
 namespace mozilla {
 namespace dom {
 
 class Blob;
 class Client;
-class FetchEventOp;
 class MessagePort;
 struct PushEventInit;
 class Request;
 class ResponseOrPromise;
 class ServiceWorker;
 class ServiceWorkerRegistrationInfo;
 
 // Defined in ServiceWorker.cpp
@@ -46,42 +45,33 @@ class CancelChannelRunnable final : publ
   CancelChannelRunnable(
       nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
       nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
       nsresult aStatus);
 
   NS_IMETHOD Run() override;
 };
 
-enum ExtendableEventResult { Rejected = 0, Resolved };
-
-class ExtendableEventCallback {
- public:
-  virtual void FinishedWithResult(ExtendableEventResult aResult) = 0;
-
-  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
-};
-
 class ExtendableEvent : public Event {
  public:
   class ExtensionsHandler {
    public:
     virtual bool WaitOnPromise(Promise& aPromise) = 0;
 
     NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
   };
 
  private:
   RefPtr<ExtensionsHandler> mExtensionsHandler;
 
  protected:
   bool WaitOnPromise(Promise& aPromise);
 
   explicit ExtendableEvent(mozilla::dom::EventTarget* aOwner);
-  ~ExtendableEvent() = default;
+  ~ExtendableEvent() {}
 
  public:
   NS_DECL_ISUPPORTS_INHERITED
 
   void SetKeepAliveHandler(ExtensionsHandler* aExtensionsHandler);
 
   virtual JSObject* WrapObjectInternal(
       JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override {
@@ -107,17 +97,16 @@ class ExtendableEvent : public Event {
   }
 
   void WaitUntil(JSContext* aCx, Promise& aPromise, ErrorResult& aRv);
 
   virtual ExtendableEvent* AsExtendableEvent() override { return this; }
 };
 
 class FetchEvent final : public ExtendableEvent {
-  RefPtr<FetchEventOp> mRespondWithHandler;
   nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
   nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
   RefPtr<Request> mRequest;
   nsCString mScriptSpec;
   nsCString mPreventDefaultScriptSpec;
   nsString mClientId;
   nsString mResultingClientId;
   uint32_t mPreventDefaultLineNumber;
@@ -138,19 +127,16 @@ class FetchEvent final : public Extendab
     return FetchEvent_Binding::Wrap(aCx, this, aGivenProto);
   }
 
   void PostInit(
       nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
       nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
       const nsACString& aScriptSpec);
 
-  void PostInit(const nsACString& aScriptSpec,
-                RefPtr<FetchEventOp> aRespondWithHandler);
-
   static already_AddRefed<FetchEvent> Constructor(
       const GlobalObject& aGlobal, const nsAString& aType,
       const FetchEventInit& aOptions, ErrorResult& aRv);
 
   bool WaitToRespond() const { return mWaitToRespond; }
 
   Request* Request_() const {
     MOZ_ASSERT(mRequest);
@@ -162,16 +148,20 @@ class FetchEvent final : public Extendab
   void GetResultingClientId(nsAString& aResultingClientId) const {
     aResultingClientId = mResultingClientId;
   }
 
   bool IsReload() const { return mIsReload; }
 
   void RespondWith(JSContext* aCx, Promise& aArg, ErrorResult& aRv);
 
+  already_AddRefed<Promise> ForwardTo(const nsAString& aUrl);
+
+  already_AddRefed<Promise> Default();
+
   // Pull in the Event version of PreventDefault so we don't get
   // shadowing warnings.
   using Event::PreventDefault;
   void PreventDefault(JSContext* aCx, CallerType aCallerType) override;
 
   void ReportCanceled();
 };
 
@@ -204,17 +194,17 @@ class PushMessageData final : public nsI
   uint8_t* GetContentsCopy();
 };
 
 class PushEvent final : public ExtendableEvent {
   RefPtr<PushMessageData> mData;
 
  protected:
   explicit PushEvent(mozilla::dom::EventTarget* aOwner);
-  ~PushEvent() = default;
+  ~PushEvent() {}
 
  public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PushEvent, ExtendableEvent)
 
   virtual JSObject* WrapObjectInternal(
       JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
--- a/dom/serviceworkers/ServiceWorkerInfo.cpp
+++ b/dom/serviceworkers/ServiceWorkerInfo.cpp
@@ -1,21 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "ServiceWorkerInfo.h"
 
-#include "ServiceWorkerPrivate.h"
 #include "ServiceWorkerScriptCache.h"
-#include "mozilla/dom/ClientIPCTypes.h"
-#include "mozilla/dom/ClientState.h"
-#include "mozilla/dom/RemoteWorkerTypes.h"
 
 namespace mozilla {
 namespace dom {
 
 using mozilla::ipc::PrincipalInfo;
 
 static_assert(nsIServiceWorkerInfo::STATE_PARSED ==
                   static_cast<uint16_t>(ServiceWorkerState::Parsed),
@@ -145,17 +141,16 @@ void ServiceWorkerInfo::UpdateState(Serv
   // TODO: Do we care that these events will race with the propagation of the
   //       state change?
   if (State() != aState) {
     mServiceWorkerPrivate->UpdateState(aState);
   }
   mDescriptor.SetState(aState);
   if (State() == ServiceWorkerState::Redundant) {
     serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
-    mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
   }
 }
 
 ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
                                      const nsACString& aScope,
                                      uint64_t aRegistrationId,
                                      uint64_t aRegistrationVersion,
                                      const nsACString& aScriptSpec,
--- a/dom/serviceworkers/ServiceWorkerManager.cpp
+++ b/dom/serviceworkers/ServiceWorkerManager.cpp
@@ -20,17 +20,16 @@
 #include "nsIScriptError.h"
 #include "nsISimpleEnumerator.h"
 #include "nsITimer.h"
 #include "nsIUploadChannel2.h"
 #include "nsServiceManagerUtils.h"
 #include "nsDebug.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIPermissionManager.h"
-#include "nsXULAppAPI.h"
 
 #include "jsapi.h"
 
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ErrorNames.h"
 #include "mozilla/LoadContext.h"
 #include "mozilla/SystemGroup.h"
@@ -72,17 +71,16 @@
 #include "ServiceWorkerInfo.h"
 #include "ServiceWorkerJobQueue.h"
 #include "ServiceWorkerManagerChild.h"
 #include "ServiceWorkerPrivate.h"
 #include "ServiceWorkerRegisterJob.h"
 #include "ServiceWorkerRegistrar.h"
 #include "ServiceWorkerRegistration.h"
 #include "ServiceWorkerScriptCache.h"
-#include "ServiceWorkerShutdownBlocker.h"
 #include "ServiceWorkerEvents.h"
 #include "ServiceWorkerUnregisterJob.h"
 #include "ServiceWorkerUpdateJob.h"
 #include "ServiceWorkerUpdaterChild.h"
 #include "ServiceWorkerUtils.h"
 
 #ifdef PostMessage
 #  undef PostMessage
@@ -256,46 +254,16 @@ class TeardownRunnable final : public Ru
   }
 
  private:
   ~TeardownRunnable() {}
 
   RefPtr<ServiceWorkerManagerChild> mActor;
 };
 
-bool ServiceWorkersAreCrossProcess() {
-  return ServiceWorkerParentInterceptEnabled() && XRE_IsE10sParentProcess();
-}
-
-const char* GetXPCOMShutdownTopic() {
-  if (ServiceWorkersAreCrossProcess()) {
-    return "profile-change-teardown";
-  }
-
-  return NS_XPCOM_SHUTDOWN_OBSERVER_ID;
-}
-
-already_AddRefed<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() {
-  AssertIsOnMainThread();
-
-  if (!ServiceWorkersAreCrossProcess()) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
-  MOZ_ASSERT(svc);
-
-  nsCOMPtr<nsIAsyncShutdownClient> barrier;
-  DebugOnly<nsresult> rv =
-      svc->GetProfileChangeTeardown(getter_AddRefs(barrier));
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-
-  return barrier.forget();
-}
-
 }  // namespace
 
 //////////////////////////
 // ServiceWorkerManager //
 //////////////////////////
 
 NS_IMPL_ADDREF(ServiceWorkerManager)
 NS_IMPL_RELEASE(ServiceWorkerManager)
@@ -307,50 +275,25 @@ NS_INTERFACE_MAP_BEGIN(ServiceWorkerMana
 NS_INTERFACE_MAP_END
 
 ServiceWorkerManager::ServiceWorkerManager()
     : mActor(nullptr), mShuttingDown(false) {}
 
 ServiceWorkerManager::~ServiceWorkerManager() {
   // The map will assert if it is not empty when destroyed.
   mRegistrationInfos.Clear();
-
-  if (!ServiceWorkersAreCrossProcess()) {
-    MOZ_ASSERT(!mActor);
-  }
-}
-
-void ServiceWorkerManager::BlockShutdownOn(
-    GenericNonExclusivePromise* aPromise) {
-  AssertIsOnMainThread();
-
-  // This may be called when in non-e10s mode with parent-intercept enabled.
-  if (!ServiceWorkersAreCrossProcess()) {
-    return;
-  }
-
-  MOZ_ASSERT(mShutdownBlocker);
-  MOZ_ASSERT(aPromise);
-
-  mShutdownBlocker->WaitOnPromise(aPromise);
+  MOZ_ASSERT(!mActor);
 }
 
 void ServiceWorkerManager::Init(ServiceWorkerRegistrar* aRegistrar) {
-  nsCOMPtr<nsIAsyncShutdownClient> shutdownBarrier = GetAsyncShutdownBarrier();
-
-  if (shutdownBarrier) {
-    mShutdownBlocker =
-        ServiceWorkerShutdownBlocker::CreateAndRegisterOn(shutdownBarrier);
-    MOZ_ASSERT(mShutdownBlocker);
-  }
-
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
     DebugOnly<nsresult> rv;
-    rv = obs->AddObserver(this, GetXPCOMShutdownTopic(), false /* ownsWeak */);
+    rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
+                          false /* ownsWeak */);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
   }
 
   if (XRE_IsParentProcess()) {
     MOZ_DIAGNOSTIC_ASSERT(aRegistrar);
 
     nsTArray<ServiceWorkerRegistrationData> data;
     aRegistrar->GetRegistrations(data);
@@ -503,23 +446,19 @@ void ServiceWorkerManager::MaybeStartShu
 
     for (auto it2 = it1.UserData()->mInfos.Iter(); !it2.Done(); it2.Next()) {
       RefPtr<ServiceWorkerRegistrationInfo> regInfo = it2.UserData();
       regInfo->Clear();
     }
     it1.UserData()->mInfos.Clear();
   }
 
-  if (mShutdownBlocker) {
-    mShutdownBlocker->StopAcceptingPromises();
-  }
-
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (obs) {
-    obs->RemoveObserver(this, GetXPCOMShutdownTopic());
+    obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
 
     if (XRE_IsParentProcess()) {
       obs->RemoveObserver(this, CLEAR_ORIGIN_DATA);
     }
   }
 
   if (!mActor) {
     return;
@@ -2331,45 +2270,60 @@ void ServiceWorkerManager::Update(
 
   ServiceWorkerUpdaterChild* actor =
       new ServiceWorkerUpdaterChild(promise, successRunnable, failureRunnable);
 
   mActor->SendPServiceWorkerUpdaterConstructor(
       actor, aPrincipal->OriginAttributesRef(), nsCString(aScope));
 }
 
+namespace {
+
+void RejectUpdateWithInvalidStateError(
+    ServiceWorkerUpdateFinishCallback& aCallback) {
+  ErrorResult error(NS_ERROR_DOM_INVALID_STATE_ERR);
+  aCallback.UpdateFailed(error);
+
+  // In case the callback does not consume the exception
+  error.SuppressException();
+}
+
+}  // namespace
+
 void ServiceWorkerManager::UpdateInternal(
     nsIPrincipal* aPrincipal, const nsACString& aScope,
     ServiceWorkerUpdateFinishCallback* aCallback) {
   MOZ_ASSERT(aPrincipal);
   MOZ_ASSERT(aCallback);
 
   nsAutoCString scopeKey;
   nsresult rv = PrincipalToScopeKey(aPrincipal, scopeKey);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
 
   RefPtr<ServiceWorkerRegistrationInfo> registration =
       GetRegistration(scopeKey, aScope);
   if (NS_WARN_IF(!registration)) {
-    ErrorResult error;
-    error.ThrowTypeError<MSG_SW_UPDATE_BAD_REGISTRATION>(
-        NS_ConvertUTF8toUTF16(aScope), NS_LITERAL_STRING("uninstalled"));
-    aCallback->UpdateFailed(error);
-
-    // In case the callback does not consume the exception
-    error.SuppressException();
     return;
   }
 
+  // "Let newestWorker be the result of running Get Newest Worker algorithm
+  // passing registration as its argument.
+  // If newestWorker is null, return a promise rejected with "InvalidStateError"
   RefPtr<ServiceWorkerInfo> newest = registration->Newest();
-  MOZ_DIAGNOSTIC_ASSERT(newest,
-                        "The Update algorithm should have been aborted already "
-                        "if there wasn't a newest worker");
+  if (!newest) {
+    RejectUpdateWithInvalidStateError(*aCallback);
+    return;
+  }
+
+  if (newest->State() == ServiceWorkerState::Installing) {
+    RejectUpdateWithInvalidStateError(*aCallback);
+    return;
+  }
 
   RefPtr<ServiceWorkerJobQueue> queue = GetOrCreateJobQueue(scopeKey, aScope);
 
   // "Invoke Update algorithm, or its equivalent, with client, registration as
   // its argument."
   RefPtr<ServiceWorkerUpdateJob> job = new ServiceWorkerUpdateJob(
       aPrincipal, registration->Scope(), newest->ScriptSpec(),
       registration->GetUpdateViaCache());
@@ -2778,17 +2732,17 @@ ServiceWorkerManager::Observe(nsISupport
     MOZ_ASSERT(XRE_IsParentProcess());
     OriginAttributesPattern pattern;
     MOZ_ALWAYS_TRUE(pattern.Init(nsAutoString(aData)));
 
     RemoveAllRegistrations(&pattern);
     return NS_OK;
   }
 
-  if (strcmp(aTopic, GetXPCOMShutdownTopic()) == 0) {
+  if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
     MaybeStartShutdown();
     return NS_OK;
   }
 
   MOZ_CRASH("Received message we aren't supposed to be registered for!");
   return NS_OK;
 }
 
--- a/dom/serviceworkers/ServiceWorkerManager.h
+++ b/dom/serviceworkers/ServiceWorkerManager.h
@@ -46,17 +46,16 @@ class PrincipalInfo;
 namespace dom {
 
 class ContentParent;
 class ServiceWorkerInfo;
 class ServiceWorkerJobQueue;
 class ServiceWorkerManagerChild;
 class ServiceWorkerPrivate;
 class ServiceWorkerRegistrar;
-class ServiceWorkerShutdownBlocker;
 
 class ServiceWorkerUpdateFinishCallback {
  protected:
   virtual ~ServiceWorkerUpdateFinishCallback() {}
 
  public:
   NS_INLINE_DECL_REFCOUNTING(ServiceWorkerUpdateFinishCallback)
 
@@ -276,18 +275,16 @@ class ServiceWorkerManager final : publi
 
   void CheckPendingReadyPromises();
 
   void RemovePendingReadyPromise(const ClientInfo& aClientInfo);
 
   void NoteInheritedController(const ClientInfo& aClientInfo,
                                const ServiceWorkerDescriptor& aController);
 
-  void BlockShutdownOn(GenericNonExclusivePromise* aPromise);
-
   nsresult GetClientRegistration(
       const ClientInfo& aClientInfo,
       ServiceWorkerRegistrationInfo** aRegistrationInfo);
 
  private:
   ServiceWorkerManager();
   ~ServiceWorkerManager();
 
@@ -383,16 +380,14 @@ class ServiceWorkerManager final : publi
   nsresult SendNotificationEvent(const nsAString& aEventName,
                                  const nsACString& aOriginSuffix,
                                  const nsACString& aScope, const nsAString& aID,
                                  const nsAString& aTitle, const nsAString& aDir,
                                  const nsAString& aLang, const nsAString& aBody,
                                  const nsAString& aTag, const nsAString& aIcon,
                                  const nsAString& aData,
                                  const nsAString& aBehavior);
-
-  RefPtr<ServiceWorkerShutdownBlocker> mShutdownBlocker;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_workers_serviceworkermanager_h
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerOp.cpp
+++ /dev/null
@@ -1,1699 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "ServiceWorkerOp.h"
-
-#include <utility>
-
-#include "jsapi.h"
-
-#include "nsCOMPtr.h"
-#include "nsContentUtils.h"
-#include "nsDebug.h"
-#include "nsError.h"
-#include "nsINamed.h"
-#include "nsIPushErrorReporter.h"
-#include "nsISupportsImpl.h"
-#include "nsITimer.h"
-#include "nsProxyRelease.h"
-#include "nsServiceManagerUtils.h"
-#include "nsTArray.h"
-#include "nsThreadUtils.h"
-
-#include "ServiceWorkerCloneData.h"
-#include "mozilla/Assertions.h"
-#include "mozilla/CycleCollectedJSContext.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/OwningNonNull.h"
-#include "mozilla/ScopeExit.h"
-#include "mozilla/SystemGroup.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/Client.h"
-#include "mozilla/dom/ExtendableMessageEventBinding.h"
-#include "mozilla/dom/FetchEventBinding.h"
-#include "mozilla/dom/FetchEventOpProxyChild.h"
-#include "mozilla/dom/InternalHeaders.h"
-#include "mozilla/dom/InternalRequest.h"
-#include "mozilla/dom/InternalResponse.h"
-#include "mozilla/dom/Notification.h"
-#include "mozilla/dom/PushEventBinding.h"
-#include "mozilla/dom/RemoteWorkerChild.h"
-#include "mozilla/dom/RemoteWorkerService.h"
-#include "mozilla/dom/Request.h"
-#include "mozilla/dom/Response.h"
-#include "mozilla/dom/RootedDictionary.h"
-#include "mozilla/dom/ServiceWorkerBinding.h"
-#include "mozilla/dom/WorkerCommon.h"
-#include "mozilla/dom/WorkerRef.h"
-#include "mozilla/ipc/IPCStreamUtils.h"
-
-namespace mozilla {
-namespace dom {
-
-namespace {
-
-class ExtendableEventKeepAliveHandler final
-    : public ExtendableEvent::ExtensionsHandler,
-      public PromiseNativeHandler {
- public:
-  NS_DECL_ISUPPORTS
-
-  static RefPtr<ExtendableEventKeepAliveHandler> Create(
-      RefPtr<ExtendableEventCallback> aCallback) {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-
-    RefPtr<ExtendableEventKeepAliveHandler> self =
-        new ExtendableEventKeepAliveHandler(std::move(aCallback));
-
-    self->mWorkerRef = StrongWorkerRef::Create(
-        GetCurrentThreadWorkerPrivate(), "ExtendableEventKeepAliveHandler",
-        [self]() { self->Cleanup(); });
-
-    if (NS_WARN_IF(!self->mWorkerRef)) {
-      return nullptr;
-    }
-
-    return self;
-  }
-
-  /**
-   * ExtendableEvent::ExtensionsHandler interface
-   */
-  bool WaitOnPromise(Promise& aPromise) override {
-    if (!mAcceptingPromises) {
-      MOZ_ASSERT(!mSelfRef, "We shouldn't be holding a self reference!");
-      return false;
-    }
-
-    if (!mSelfRef) {
-      MOZ_ASSERT(!mPendingPromisesCount);
-      mSelfRef = this;
-    }
-
-    ++mPendingPromisesCount;
-    aPromise.AppendNativeHandler(this);
-
-    return true;
-  }
-
-  /**
-   * PromiseNativeHandler interface
-   */
-  void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
-    RemovePromise(Resolved);
-  }
-
-  void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
-    RemovePromise(Rejected);
-  }
-
-  void MaybeDone() {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-
-    if (mPendingPromisesCount) {
-      return;
-    }
-
-    if (mCallback) {
-      mCallback->FinishedWithResult(mRejected ? Rejected : Resolved);
-    }
-
-    Cleanup();
-  }
-
- private:
-  /**
-   * This class is useful for the case where pending microtasks will continue
-   * extending the event, which means that the event is not "done." For example:
-   *
-   * // `e` is an ExtendableEvent, `p` is a Promise
-   * e.waitUntil(p);
-   * p.then(() => e.waitUntil(otherPromise));
-   */
-  class MaybeDoneRunner : public MicroTaskRunnable {
-   public:
-    explicit MaybeDoneRunner(RefPtr<ExtendableEventKeepAliveHandler> aHandler)
-        : mHandler(std::move(aHandler)) {}
-
-    void Run(AutoSlowOperation& /* unused */) override {
-      mHandler->MaybeDone();
-    }
-
-   private:
-    RefPtr<ExtendableEventKeepAliveHandler> mHandler;
-  };
-
-  explicit ExtendableEventKeepAliveHandler(
-      RefPtr<ExtendableEventCallback> aCallback)
-      : mCallback(std::move(aCallback)) {}
-
-  ~ExtendableEventKeepAliveHandler() { Cleanup(); }
-
-  void Cleanup() {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-
-    mSelfRef = nullptr;
-    mWorkerRef = nullptr;
-    mCallback = nullptr;
-    mAcceptingPromises = false;
-  }
-
-  void RemovePromise(ExtendableEventResult aResult) {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-    MOZ_DIAGNOSTIC_ASSERT(mPendingPromisesCount > 0);
-
-    // NOTE: mSelfRef can be nullptr here if MaybeCleanup() was just called
-    // before a promise settled. This can happen, for example, if the worker
-    // thread is being terminated for running too long, browser shutdown, etc.
-
-    mRejected |= (aResult == Rejected);
-
-    --mPendingPromisesCount;
-    if (mPendingPromisesCount) {
-      return;
-    }
-
-    CycleCollectedJSContext* cx = CycleCollectedJSContext::Get();
-    MOZ_ASSERT(cx);
-
-    RefPtr<MaybeDoneRunner> r = new MaybeDoneRunner(this);
-    cx->DispatchToMicroTask(r.forget());
-  }
-
-  /**
-   * We start holding a self reference when the first extension promise is
-   * added, and this reference is released when the last promise settles or
-   * when the worker is shutting down.
-   *
-   * This is needed in the case that we're waiting indefinitely on a to-be-GC'ed
-   * promise that's no longer reachable and will never be settled.
-   */
-  RefPtr<ExtendableEventKeepAliveHandler> mSelfRef;
-
-  RefPtr<StrongWorkerRef> mWorkerRef;
-
-  RefPtr<ExtendableEventCallback> mCallback;
-
-  uint32_t mPendingPromisesCount = 0;
-
-  bool mRejected = false;
-  bool mAcceptingPromises = true;
-};
-
-NS_IMPL_ISUPPORTS0(ExtendableEventKeepAliveHandler)
-
-nsresult DispatchExtendableEventOnWorkerScope(
-    JSContext* aCx, WorkerGlobalScope* aWorkerScope, ExtendableEvent* aEvent,
-    RefPtr<ExtendableEventCallback> aCallback) {
-  MOZ_ASSERT(aCx);
-  MOZ_ASSERT(aWorkerScope);
-  MOZ_ASSERT(aEvent);
-
-  nsCOMPtr<nsIGlobalObject> globalObject = aWorkerScope;
-  WidgetEvent* internalEvent = aEvent->WidgetEventPtr();
-
-  RefPtr<ExtendableEventKeepAliveHandler> keepAliveHandler =
-      ExtendableEventKeepAliveHandler::Create(std::move(aCallback));
-  if (NS_WARN_IF(!keepAliveHandler)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  // This must be always set *before* dispatching the event, otherwise
-  // waitUntil() calls will fail.
-  aEvent->SetKeepAliveHandler(keepAliveHandler);
-
-  ErrorResult result;
-  aWorkerScope->DispatchEvent(*aEvent, result);
-  if (NS_WARN_IF(result.Failed())) {
-    result.SuppressException();
-    return NS_ERROR_FAILURE;
-  }
-
-  keepAliveHandler->MaybeDone();
-
-  // We don't block the event when getting an exception but still report the
-  // error message. NOTE: this will not stop the event.
-  if (internalEvent->mFlags.mExceptionWasRaised) {
-    return NS_ERROR_XPC_JS_THREW_EXCEPTION;
-  }
-
-  return NS_OK;
-}
-
-bool DispatchFailed(nsresult aStatus) {
-  return NS_FAILED(aStatus) && aStatus != NS_ERROR_XPC_JS_THREW_EXCEPTION;
-}
-
-}  // anonymous namespace
-
-class ServiceWorkerOp::ServiceWorkerOpRunnable : public WorkerRunnable {
- public:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  ServiceWorkerOpRunnable(RefPtr<ServiceWorkerOp> aOwner,
-                          WorkerPrivate* aWorkerPrivate)
-      : WorkerRunnable(aWorkerPrivate), mOwner(std::move(aOwner)) {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(mOwner);
-    MOZ_ASSERT(aWorkerPrivate);
-  }
-
- private:
-  ~ServiceWorkerOpRunnable() = default;
-
-  bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(mOwner);
-
-    bool rv = mOwner->Exec(aCx, aWorkerPrivate);
-    Unused << NS_WARN_IF(!rv);
-    mOwner = nullptr;
-
-    return rv;
-  }
-
-  nsresult Cancel() override {
-    MOZ_ASSERT(mOwner);
-
-    mOwner->RejectAll(NS_ERROR_DOM_ABORT_ERR);
-    mOwner = nullptr;
-
-    return WorkerRunnable::Cancel();
-  }
-
-  RefPtr<ServiceWorkerOp> mOwner;
-};
-
-NS_IMPL_ISUPPORTS_INHERITED0(ServiceWorkerOp::ServiceWorkerOpRunnable,
-                             WorkerRunnable)
-
-bool ServiceWorkerOp::MaybeStart(RemoteWorkerChild* aOwner,
-                                 RemoteWorkerChild::State& aState) {
-  MOZ_ASSERT(!mStarted);
-  MOZ_ASSERT(aOwner);
-  MOZ_ASSERT(aOwner->GetOwningEventTarget()->IsOnCurrentThread());
-
-  MOZ_ACCESS_THREAD_BOUND(aOwner->mLauncherData, launcherData);
-
-  if (NS_WARN_IF(!launcherData->mIPCActive)) {
-    RejectAll(NS_ERROR_DOM_ABORT_ERR);
-    mStarted = true;
-    return true;
-  }
-
-  // Allow termination to happen while the Service Worker is initializing.
-  if (aState.is<Pending>() && !IsTerminationOp()) {
-    return false;
-  }
-
-  if (NS_WARN_IF(aState.is<RemoteWorkerChild::PendingTerminated>()) ||
-      NS_WARN_IF(aState.is<RemoteWorkerChild::Terminated>())) {
-    RejectAll(NS_ERROR_DOM_INVALID_STATE_ERR);
-    mStarted = true;
-    return true;
-  }
-
-  MOZ_ASSERT(aState.is<RemoteWorkerChild::Running>() || IsTerminationOp());
-
-  RefPtr<ServiceWorkerOp> self = this;
-
-  if (IsTerminationOp()) {
-    aOwner->GetTerminationPromise()->Then(
-        GetCurrentThreadSerialEventTarget(), __func__,
-        [self](
-            const GenericNonExclusivePromise::ResolveOrRejectValue& aResult) {
-          MOZ_ASSERT(!self->mPromiseHolder.IsEmpty());
-
-          if (NS_WARN_IF(aResult.IsReject())) {
-            self->mPromiseHolder.Reject(aResult.RejectValue(), __func__);
-            return;
-          }
-
-          self->mPromiseHolder.Resolve(NS_OK, __func__);
-        });
-  }
-
-  RefPtr<RemoteWorkerChild> owner = aOwner;
-
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-      __func__, [self = std::move(self), owner = std::move(owner)]() mutable {
-        auto lock = owner->mState.Lock();
-        auto& state = lock.ref();
-
-        if (NS_WARN_IF(!state.is<Running>() && !self->IsTerminationOp())) {
-          self->RejectAll(NS_ERROR_DOM_INVALID_STATE_ERR);
-          return;
-        }
-
-        if (self->IsTerminationOp()) {
-          owner->CloseWorkerOnMainThread(state);
-        } else {
-          MOZ_ASSERT(state.is<Running>());
-
-          if (NS_WARN_IF(
-                  state.as<Running>().mWorkerPrivate->ParentStatusProtected() >
-                  Running)) {
-            owner->GetTerminationPromise()->Then(
-                GetCurrentThreadSerialEventTarget(), __func__,
-                [self = std::move(self)](
-                    const GenericNonExclusivePromise::ResolveOrRejectValue&) {
-                  MOZ_ASSERT(!self->mPromiseHolder.IsEmpty());
-                  self->RejectAll(NS_ERROR_DOM_ABORT_ERR);
-                });
-
-            owner->CloseWorkerOnMainThread(state);
-            return;
-          }
-
-          RefPtr<WorkerRunnable> workerRunnable =
-              self->GetRunnable(state.as<Running>().mWorkerPrivate);
-
-          if (NS_WARN_IF(!workerRunnable->Dispatch())) {
-            self->RejectAll(NS_ERROR_FAILURE);
-          }
-        }
-
-        nsCOMPtr<nsIEventTarget> target = owner->GetOwningEventTarget();
-        NS_ProxyRelease(__func__, target, owner.forget());
-      });
-
-  mStarted = true;
-
-  MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
-
-  return true;
-}
-
-void ServiceWorkerOp::Cancel() { RejectAll(NS_ERROR_DOM_ABORT_ERR); }
-
-ServiceWorkerOp::ServiceWorkerOp(
-    const ServiceWorkerOpArgs& aArgs,
-    std::function<void(const ServiceWorkerOpResult&)>&& aCallback)
-    : mArgs(aArgs) {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-
-  RefPtr<ServiceWorkerOpPromise> promise = mPromiseHolder.Ensure(__func__);
-
-  promise->Then(
-      GetCurrentThreadSerialEventTarget(), __func__,
-      [callback = std::move(aCallback)](
-          ServiceWorkerOpPromise::ResolveOrRejectValue&& aResult) mutable {
-        if (NS_WARN_IF(aResult.IsReject())) {
-          MOZ_ASSERT(NS_FAILED(aResult.RejectValue()));
-          callback(aResult.RejectValue());
-          return;
-        }
-
-        callback(aResult.ResolveValue());
-      });
-}
-
-ServiceWorkerOp::~ServiceWorkerOp() {
-  Unused << NS_WARN_IF(!mPromiseHolder.IsEmpty());
-  mPromiseHolder.RejectIfExists(NS_ERROR_DOM_ABORT_ERR, __func__);
-}
-
-bool ServiceWorkerOp::Started() const {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-
-  return mStarted;
-}
-
-bool ServiceWorkerOp::IsTerminationOp() const {
-  return mArgs.type() ==
-         ServiceWorkerOpArgs::TServiceWorkerTerminateWorkerOpArgs;
-}
-
-RefPtr<WorkerRunnable> ServiceWorkerOp::GetRunnable(
-    WorkerPrivate* aWorkerPrivate) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aWorkerPrivate);
-
-  return new ServiceWorkerOpRunnable(this, aWorkerPrivate);
-}
-
-void ServiceWorkerOp::RejectAll(nsresult aStatus) {
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-  mPromiseHolder.Reject(aStatus, __func__);
-}
-
-class CheckScriptEvaluationOp final : public ServiceWorkerOp {
-  using ServiceWorkerOp::ServiceWorkerOp;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CheckScriptEvaluationOp, override)
-
- private:
-  ~CheckScriptEvaluationOp() = default;
-
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-    ServiceWorkerCheckScriptEvaluationOpResult result;
-    result.workerScriptExecutedSuccessfully() =
-        aWorkerPrivate->WorkerScriptExecutedSuccessfully();
-    result.fetchHandlerWasAdded() = aWorkerPrivate->FetchHandlerWasAdded();
-
-    mPromiseHolder.Resolve(result, __func__);
-
-    return true;
-  }
-};
-
-class TerminateServiceWorkerOp final : public ServiceWorkerOp {
-  using ServiceWorkerOp::ServiceWorkerOp;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TerminateServiceWorkerOp, override)
-
- private:
-  ~TerminateServiceWorkerOp() = default;
-
-  bool Exec(JSContext*, WorkerPrivate*) override {
-    MOZ_ASSERT_UNREACHABLE(
-        "Worker termination should be handled in "
-        "`ServiceWorkerOp::MaybeStart()`");
-
-    return false;
-  }
-};
-
-class UpdateServiceWorkerStateOp final : public ServiceWorkerOp {
-  using ServiceWorkerOp::ServiceWorkerOp;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UpdateServiceWorkerStateOp, override);
-
- private:
-  class UpdateStateOpRunnable final : public MainThreadWorkerControlRunnable {
-   public:
-    NS_DECL_ISUPPORTS_INHERITED
-
-    UpdateStateOpRunnable(RefPtr<UpdateServiceWorkerStateOp> aOwner,
-                          WorkerPrivate* aWorkerPrivate)
-        : MainThreadWorkerControlRunnable(aWorkerPrivate),
-          mOwner(std::move(aOwner)) {
-      AssertIsOnMainThread();
-      MOZ_ASSERT(mOwner);
-      MOZ_ASSERT(aWorkerPrivate);
-    }
-
-   private:
-    ~UpdateStateOpRunnable() = default;
-
-    bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-      MOZ_ASSERT(aWorkerPrivate);
-      aWorkerPrivate->AssertIsOnWorkerThread();
-      MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-      MOZ_ASSERT(mOwner);
-
-      Unused << mOwner->Exec(aCx, aWorkerPrivate);
-      mOwner = nullptr;
-
-      return true;
-    }
-
-    nsresult Cancel() override {
-      MOZ_ASSERT(mOwner);
-
-      mOwner->RejectAll(NS_ERROR_DOM_ABORT_ERR);
-      mOwner = nullptr;
-
-      return MainThreadWorkerControlRunnable::Cancel();
-    }
-
-    RefPtr<UpdateServiceWorkerStateOp> mOwner;
-  };
-
-  ~UpdateServiceWorkerStateOp() = default;
-
-  RefPtr<WorkerRunnable> GetRunnable(WorkerPrivate* aWorkerPrivate) override {
-    AssertIsOnMainThread();
-    MOZ_ASSERT(aWorkerPrivate);
-    MOZ_ASSERT(mArgs.type() ==
-               ServiceWorkerOpArgs::TServiceWorkerUpdateStateOpArgs);
-
-    return new UpdateStateOpRunnable(this, aWorkerPrivate);
-  }
-
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-    ServiceWorkerState state =
-        mArgs.get_ServiceWorkerUpdateStateOpArgs().state();
-    aWorkerPrivate->UpdateServiceWorkerState(state);
-
-    mPromiseHolder.Resolve(NS_OK, __func__);
-
-    return true;
-  }
-};
-
-NS_IMPL_ISUPPORTS_INHERITED0(UpdateServiceWorkerStateOp::UpdateStateOpRunnable,
-                             MainThreadWorkerControlRunnable)
-
-void ExtendableEventOp::FinishedWithResult(ExtendableEventResult aResult) {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  mPromiseHolder.Resolve(aResult == Resolved ? NS_OK : NS_ERROR_FAILURE,
-                         __func__);
-}
-
-class LifeCycleEventOp final : public ExtendableEventOp {
-  using ExtendableEventOp::ExtendableEventOp;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LifeCycleEventOp, override)
-
- private:
-  ~LifeCycleEventOp() = default;
-
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-    RefPtr<ExtendableEvent> event;
-    RefPtr<EventTarget> target = aWorkerPrivate->GlobalScope();
-
-    const nsString& eventName =
-        mArgs.get_ServiceWorkerLifeCycleEventOpArgs().eventName();
-
-    if (eventName.EqualsASCII("install") || eventName.EqualsASCII("activate")) {
-      ExtendableEventInit init;
-      init.mBubbles = false;
-      init.mCancelable = false;
-      event = ExtendableEvent::Constructor(target, eventName, init);
-    } else {
-      MOZ_CRASH("Unexpected lifecycle event");
-    }
-
-    event->SetTrusted(true);
-
-    nsresult rv = DispatchExtendableEventOnWorkerScope(
-        aCx, aWorkerPrivate->GlobalScope(), event, this);
-
-    if (NS_WARN_IF(DispatchFailed(rv))) {
-      RejectAll(rv);
-    }
-
-    return DispatchFailed(rv);
-  }
-};
-
-/**
- * PushEventOp
- */
-class PushEventOp final : public ExtendableEventOp {
-  using ExtendableEventOp::ExtendableEventOp;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PushEventOp, override)
-
- private:
-  ~PushEventOp() = default;
-
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-    ErrorResult result;
-
-    auto scopeExit = MakeScopeExit([&] {
-      MOZ_ASSERT(result.Failed());
-
-      RejectAll(result.StealNSResult());
-      ReportError(aWorkerPrivate);
-    });
-
-    const ServiceWorkerPushEventOpArgs& args =
-        mArgs.get_ServiceWorkerPushEventOpArgs();
-
-    PushEventInit pushEventInit;
-
-    if (args.data().type() != OptionalPushData::Tvoid_t) {
-      auto& bytes = args.data().get_ArrayOfuint8_t();
-      JSObject* data =
-          Uint8Array::Create(aCx, bytes.Length(), bytes.Elements());
-
-      if (!data) {
-        result = ErrorResult(NS_ERROR_FAILURE);
-        return false;
-      }
-
-      DebugOnly<bool> inited =
-          pushEventInit.mData.Construct().SetAsArrayBufferView().Init(data);
-      MOZ_ASSERT(inited);
-    }
-
-    pushEventInit.mBubbles = false;
-    pushEventInit.mCancelable = false;
-
-    GlobalObject globalObj(aCx, aWorkerPrivate->GlobalScope()->GetWrapper());
-    RefPtr<PushEvent> pushEvent = PushEvent::Constructor(
-        globalObj, NS_LITERAL_STRING("push"), pushEventInit, result);
-
-    if (NS_WARN_IF(result.Failed())) {
-      return false;
-    }
-
-    pushEvent->SetTrusted(true);
-
-    scopeExit.release();
-
-    nsresult rv = DispatchExtendableEventOnWorkerScope(
-        aCx, aWorkerPrivate->GlobalScope(), pushEvent, this);
-
-    if (NS_FAILED(rv)) {
-      if (NS_WARN_IF(DispatchFailed(rv))) {
-        RejectAll(rv);
-      }
-
-      // We don't cancel WorkerPrivate when catching an exception.
-      ReportError(aWorkerPrivate,
-                  nsIPushErrorReporter::DELIVERY_UNCAUGHT_EXCEPTION);
-    }
-
-    return DispatchFailed(rv);
-  }
-
-  void FinishedWithResult(ExtendableEventResult aResult) override {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-
-    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-
-    if (aResult == Rejected) {
-      ReportError(workerPrivate,
-                  nsIPushErrorReporter::DELIVERY_UNHANDLED_REJECTION);
-    }
-
-    ExtendableEventOp::FinishedWithResult(aResult);
-  }
-
-  void ReportError(
-      WorkerPrivate* aWorkerPrivate,
-      uint16_t aError = nsIPushErrorReporter::DELIVERY_INTERNAL_ERROR) {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-
-    if (NS_WARN_IF(aError > nsIPushErrorReporter::DELIVERY_INTERNAL_ERROR) ||
-        mArgs.get_ServiceWorkerPushEventOpArgs().messageId().IsEmpty()) {
-      return;
-    }
-
-    nsString messageId = mArgs.get_ServiceWorkerPushEventOpArgs().messageId();
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-        __func__, [messageId = std::move(messageId), error = aError] {
-          nsCOMPtr<nsIPushErrorReporter> reporter =
-              do_GetService("@mozilla.org/push/Service;1");
-
-          if (reporter) {
-            nsresult rv = reporter->ReportDeliveryError(messageId, error);
-            Unused << NS_WARN_IF(NS_FAILED(rv));
-          }
-        });
-
-    MOZ_ALWAYS_SUCCEEDS(aWorkerPrivate->DispatchToMainThread(r.forget()));
-  }
-};
-
-class PushSubscriptionChangeEventOp final : public ExtendableEventOp {
-  using ExtendableEventOp::ExtendableEventOp;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PushSubscriptionChangeEventOp, override)
-
- private:
-  ~PushSubscriptionChangeEventOp() = default;
-
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-    RefPtr<EventTarget> target = aWorkerPrivate->GlobalScope();
-
-    ExtendableEventInit init;
-    init.mBubbles = false;
-    init.mCancelable = false;
-
-    RefPtr<ExtendableEvent> event = ExtendableEvent::Constructor(
-        target, NS_LITERAL_STRING("pushsubscriptionchange"), init);
-    event->SetTrusted(true);
-
-    nsresult rv = DispatchExtendableEventOnWorkerScope(
-        aCx, aWorkerPrivate->GlobalScope(), event, this);
-
-    if (NS_WARN_IF(DispatchFailed(rv))) {
-      RejectAll(rv);
-    }
-
-    return DispatchFailed(rv);
-  }
-};
-
-class NotificationEventOp : public ExtendableEventOp,
-                            public nsITimerCallback,
-                            public nsINamed {
-  using ExtendableEventOp::ExtendableEventOp;
-
- public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-
- private:
-  ~NotificationEventOp() {
-    MOZ_DIAGNOSTIC_ASSERT(!mTimer);
-    MOZ_DIAGNOSTIC_ASSERT(!mWorkerRef);
-  }
-
-  void ClearWindowAllowed(WorkerPrivate* aWorkerPrivate) {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-
-    if (!mTimer) {
-      return;
-    }
-
-    // This might be executed after the global was unrooted, in which case
-    // GlobalScope() will return null. Making the check here just to be safe.
-    WorkerGlobalScope* globalScope = aWorkerPrivate->GlobalScope();
-    if (!globalScope) {
-      return;
-    }
-
-    globalScope->ConsumeWindowInteraction();
-    mTimer->Cancel();
-    mTimer = nullptr;
-
-    mWorkerRef = nullptr;
-  }
-
-  void StartClearWindowTimer(WorkerPrivate* aWorkerPrivate) {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(!mTimer);
-
-    nsresult rv;
-    nsCOMPtr<nsITimer> timer =
-        NS_NewTimer(aWorkerPrivate->ControlEventTarget());
-    if (NS_WARN_IF(!timer)) {
-      return;
-    }
-
-    MOZ_ASSERT(!mWorkerRef);
-    RefPtr<NotificationEventOp> self = this;
-    mWorkerRef = StrongWorkerRef::Create(
-        aWorkerPrivate, "NotificationEventOp", [self = std::move(self)] {
-          // We could try to hold the worker alive until the timer fires, but
-          // other APIs are not likely to work in this partially shutdown state.
-          // We might as well let the worker thread exit.
-          self->ClearWindowAllowed(self->mWorkerRef->Private());
-        });
-
-    if (!mWorkerRef) {
-      return;
-    }
-
-    aWorkerPrivate->GlobalScope()->AllowWindowInteraction();
-    timer.swap(mTimer);
-
-    // We swap first and then initialize the timer so that even if initializing
-    // fails, we still clean the busy count and interaction count correctly.
-    // The timer can't be initialized before modyfing the busy count since the
-    // timer thread could run and call the timeout but the worker may
-    // already be terminating and modifying the busy count could fail.
-    uint32_t delay = mArgs.get_ServiceWorkerNotificationEventOpArgs()
-                         .disableOpenClickDelay();
-    rv = mTimer->InitWithCallback(this, delay, nsITimer::TYPE_ONE_SHOT);
-
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      ClearWindowAllowed(aWorkerPrivate);
-      return;
-    }
-  }
-
-  // ExtendableEventOp interface
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-    RefPtr<EventTarget> target = aWorkerPrivate->GlobalScope();
-
-    ServiceWorkerNotificationEventOpArgs& args =
-        mArgs.get_ServiceWorkerNotificationEventOpArgs();
-
-    ErrorResult result;
-    RefPtr<Notification> notification = Notification::ConstructFromFields(
-        aWorkerPrivate->GlobalScope(), args.id(), args.title(), args.dir(),
-        args.lang(), args.body(), args.tag(), args.icon(), args.data(),
-        args.scope(), result);
-
-    if (NS_WARN_IF(result.Failed())) {
-      return false;
-    }
-
-    NotificationEventInit init;
-    init.mNotification = notification;
-    init.mBubbles = false;
-    init.mCancelable = false;
-
-    RefPtr<NotificationEvent> notificationEvent =
-        NotificationEvent::Constructor(target, args.eventName(), init, result);
-
-    if (NS_WARN_IF(result.Failed())) {
-      return false;
-    }
-
-    notificationEvent->SetTrusted(true);
-
-    if (args.eventName().EqualsLiteral("notificationclick")) {
-      StartClearWindowTimer(aWorkerPrivate);
-    }
-
-    nsresult rv = DispatchExtendableEventOnWorkerScope(
-        aCx, aWorkerPrivate->GlobalScope(), notificationEvent, this);
-
-    if (NS_WARN_IF(DispatchFailed(rv))) {
-      // This will reject mPromiseHolder.
-      FinishedWithResult(Rejected);
-    }
-
-    return DispatchFailed(rv);
-  }
-
-  void FinishedWithResult(ExtendableEventResult aResult) override {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-
-    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-    MOZ_ASSERT(workerPrivate);
-
-    ClearWindowAllowed(workerPrivate);
-
-    ExtendableEventOp::FinishedWithResult(aResult);
-  }
-
-  // nsITimerCallback interface
-  NS_IMETHOD Notify(nsITimer* aTimer) override {
-    MOZ_DIAGNOSTIC_ASSERT(mTimer == aTimer);
-    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-    ClearWindowAllowed(workerPrivate);
-    return NS_OK;
-  }
-
-  // nsINamed interface
-  NS_IMETHOD GetName(nsACString& aName) override {
-    aName.AssignLiteral("NotificationEventOp");
-    return NS_OK;
-  }
-
-  nsCOMPtr<nsITimer> mTimer;
-  RefPtr<StrongWorkerRef> mWorkerRef;
-};
-
-NS_IMPL_ISUPPORTS(NotificationEventOp, nsITimerCallback, nsINamed)
-
-class MessageEventOp final : public ExtendableEventOp {
-  using ExtendableEventOp::ExtendableEventOp;
-
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MessageEventOp, override)
-
-  MessageEventOp(const ServiceWorkerOpArgs& aArgs,
-                 std::function<void(const ServiceWorkerOpResult&)>&& aCallback)
-      : ExtendableEventOp(aArgs, std::move(aCallback)),
-        mData(new ServiceWorkerCloneData()) {
-    mData->CopyFromClonedMessageDataForBackgroundChild(
-        mArgs.get_ServiceWorkerMessageEventOpArgs().clonedData());
-  }
-
- private:
-  ~MessageEventOp() = default;
-
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override {
-    MOZ_ASSERT(aWorkerPrivate);
-    aWorkerPrivate->AssertIsOnWorkerThread();
-    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-    MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-    JS::Rooted<JS::Value> messageData(aCx);
-    nsCOMPtr<nsIGlobalObject> sgo = aWorkerPrivate->GlobalScope();
-    ErrorResult rv;
-    mData->Read(aCx, &messageData, rv);
-
-    // If deserialization fails, we will fire a messageerror event
-    bool deserializationFailed = rv.ErrorCodeIs(NS_ERROR_DOM_DATA_CLONE_ERR);
-
-    if (!deserializationFailed && NS_WARN_IF(rv.Failed())) {
-      RejectAll(rv.StealNSResult());
-      return true;
-    }
-
-    Sequence<OwningNonNull<MessagePort>> ports;
-    if (!mData->TakeTransferredPortsAsSequence(ports)) {
-      RejectAll(NS_ERROR_FAILURE);
-      return true;
-    }
-
-    RootedDictionary<ExtendableMessageEventInit> init(aCx);
-
-    init.mBubbles = false;
-    init.mCancelable = false;
-
-    // On a messageerror event, we disregard ports:
-    // https://w3c.github.io/ServiceWorker/#service-worker-postmessage
-    if (!deserializationFailed) {
-      init.mData = messageData;
-      init.mPorts = ports;
-    }
-
-    init.mSource.SetValue().SetAsClient() = new Client(
-        sgo, mArgs.get_ServiceWorkerMessageEventOpArgs().clientInfoAndState());
-
-    rv = NS_OK;
-    RefPtr<EventTarget> target = aWorkerPrivate->GlobalScope();
-    RefPtr<ExtendableMessageEvent> extendableEvent =
-        ExtendableMessageEvent::Constructor(
-            target,
-            deserializationFailed ? NS_LITERAL_STRING("messageerror")
-                                  : NS_LITERAL_STRING("message"),
-            init, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      RejectAll(rv.StealNSResult());
-      return false;
-    }
-
-    extendableEvent->SetTrusted(true);
-
-    nsresult rv2 = DispatchExtendableEventOnWorkerScope(
-        aCx, aWorkerPrivate->GlobalScope(), extendableEvent, this);
-
-    if (NS_WARN_IF(DispatchFailed(rv2))) {
-      RejectAll(rv2);
-    }
-
-    return DispatchFailed(rv2);
-  }
-
-  RefPtr<ServiceWorkerCloneData> mData;
-};
-
-/**
- * Used for ScopeExit-style network request cancelation in
- * `ResolvedCallback()` (e.g. if `FetchEvent::RespondWith()` is resolved with
- * a non-JS object).
- */
-class MOZ_STACK_CLASS FetchEventOp::AutoCancel {
- public:
-  explicit AutoCancel(FetchEventOp* aOwner)
-      : mOwner(aOwner),
-        mLine(0),
-        mColumn(0),
-        mMessageName(NS_LITERAL_CSTRING("InterceptionFailedWithURL")) {
-    MOZ_ASSERT(IsCurrentThreadRunningWorker());
-    MOZ_ASSERT(mOwner);
-
-    nsAutoString requestURL;
-    mOwner->GetRequestURL(requestURL);
-    mParams.AppendElement(requestURL);
-  }
-
-  ~AutoCancel() {
-    if (mOwner) {
-      if (mSourceSpec.IsEmpty()) {
-        mOwner->AsyncLog(mMessageName, std::move(mParams));
-      } else {
-        mOwner->AsyncLog(mSourceSpec, mLine, mColumn, mMessageName,
-                         std::move(mParams));
-      }
-
-      MOZ_ASSERT(!mOwner->mRespondWithPromiseHolder.IsEmpty());
-      mOwner->mRespondWithPromiseHolder.Reject(NS_ERROR_INTERCEPTION_FAILED,
-                                               __func__);
-    }
-  }
-
-  // This function steals the error message from a ErrorResult.
-  void SetCancelErrorResult(JSContext* aCx, ErrorResult& aRv) {
-    MOZ_DIAGNOSTIC_ASSERT(aRv.Failed());
-    MOZ_DIAGNOSTIC_ASSERT(!JS_IsExceptionPending(aCx));
-
-    // Storing the error as exception in the JSContext.
-    if (!aRv.MaybeSetPendingException(aCx)) {
-      return;
-    }
-
-    MOZ_ASSERT(!aRv.Failed());
-
-    // Let's take the pending exception.
-    JS::Rooted<JS::Value> exn(aCx);
-    if (!JS_GetPendingException(aCx, &exn)) {
-      return;
-    }
-
-    JS_ClearPendingException(aCx);
-
-    // Converting the exception in a js::ErrorReport.
-    js::ErrorReport report(aCx);
-    if (!report.init(aCx, exn, js::ErrorReport::WithSideEffects)) {
-      JS_ClearPendingException(aCx);
-      return;
-    }
-
-    MOZ_ASSERT(mOwner);
-    MOZ_ASSERT(mMessageName.EqualsLiteral("InterceptionFailedWithURL"));
-    MOZ_ASSERT(mParams.Length() == 1);
-
-    // Let's store the error message here.
-    mMessageName.Assign(report.toStringResult().c_str());
-    mParams.Clear();
-  }
-
-  template <typename... Params>
-  void SetCancelMessage(const nsACString& aMessageName, Params&&... aParams) {
-    MOZ_ASSERT(mOwner);
-    MOZ_ASSERT(mMessageName.EqualsLiteral("InterceptionFailedWithURL"));
-    MOZ_ASSERT(mParams.Length() == 1);
-    mMessageName = aMessageName;
-    mParams.Clear();
-    StringArrayAppender::Append(mParams, sizeof...(Params),
-                                std::forward<Params>(aParams)...);
-  }
-
-  template <typename... Params>
-  void SetCancelMessageAndLocation(const nsACString& aSourceSpec,
-                                   uint32_t aLine, uint32_t aColumn,
-                                   const nsACString& aMessageName,
-                                   Params&&... aParams) {
-    MOZ_ASSERT(mOwner);
-    MOZ_ASSERT(mMessageName.EqualsLiteral("InterceptionFailedWithURL"));
-    MOZ_ASSERT(mParams.Length() == 1);
-
-    mSourceSpec = aSourceSpec;
-    mLine = aLine;
-    mColumn = aColumn;
-
-    mMessageName = aMessageName;
-    mParams.Clear();
-    StringArrayAppender::Append(mParams, sizeof...(Params),
-                                std::forward<Params>(aParams)...);
-  }
-
-  void Reset() { mOwner = nullptr; }
-
- private:
-  FetchEventOp* MOZ_NON_OWNING_REF mOwner;
-  nsCString mSourceSpec;
-  uint32_t mLine;
-  uint32_t mColumn;
-  nsCString mMessageName;
-  nsTArray<nsString> mParams;
-};
-
-NS_IMPL_ISUPPORTS0(FetchEventOp)
-
-void FetchEventOp::SetActor(RefPtr<FetchEventOpProxyChild> aActor) {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-  MOZ_ASSERT(!Started());
-  MOZ_ASSERT(!mActor);
-
-  mActor = std::move(aActor);
-}
-
-void FetchEventOp::RevokeActor(FetchEventOpProxyChild* aActor) {
-  MOZ_ASSERT(aActor);
-  MOZ_ASSERT_IF(mActor, mActor == aActor);
-
-  mActor = nullptr;
-}
-
-RefPtr<FetchEventRespondWithPromise> FetchEventOp::GetRespondWithPromise() {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-  MOZ_ASSERT(!Started());
-  MOZ_ASSERT(mRespondWithPromiseHolder.IsEmpty());
-
-  return mRespondWithPromiseHolder.Ensure(__func__);
-}
-
-void FetchEventOp::RespondWithCalledAt(const nsCString& aRespondWithScriptSpec,
-                                       uint32_t aRespondWithLineNumber,
-                                       uint32_t aRespondWithColumnNumber) {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(!mRespondWithClosure);
-
-  mRespondWithClosure.emplace(aRespondWithScriptSpec, aRespondWithLineNumber,
-                              aRespondWithColumnNumber);
-}
-
-void FetchEventOp::ReportCanceled(const nsCString& aPreventDefaultScriptSpec,
-                                  uint32_t aPreventDefaultLineNumber,
-                                  uint32_t aPreventDefaultColumnNumber) {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(mActor);
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  nsString requestURL;
-  GetRequestURL(requestURL);
-
-  AsyncLog(aPreventDefaultScriptSpec, aPreventDefaultLineNumber,
-           aPreventDefaultColumnNumber,
-           NS_LITERAL_CSTRING("InterceptionCanceledWithURL"),
-           {std::move(requestURL)});
-}
-
-FetchEventOp::~FetchEventOp() {
-  mRespondWithPromiseHolder.RejectIfExists(NS_ERROR_DOM_ABORT_ERR, __func__);
-
-  if (mActor) {
-    NS_ProxyRelease("FetchEventOp::mActor", RemoteWorkerService::Thread(),
-                    mActor.forget());
-  }
-}
-
-void FetchEventOp::RejectAll(nsresult aStatus) {
-  MOZ_ASSERT(!mRespondWithPromiseHolder.IsEmpty());
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  mRespondWithPromiseHolder.Reject(aStatus, __func__);
-  mPromiseHolder.Reject(aStatus, __func__);
-}
-
-void FetchEventOp::FinishedWithResult(ExtendableEventResult aResult) {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-  MOZ_ASSERT(!mResult);
-
-  mResult.emplace(aResult);
-
-  /**
-   * This should only return early if neither waitUntil() nor respondWith()
-   * are called. The early return is so that mRespondWithPromiseHolder has a
-   * chance to settle before mPromiseHolder does.
-   */
-  if (!mPostDispatchChecksDone) {
-    return;
-  }
-
-  MaybeFinished();
-}
-
-void FetchEventOp::MaybeFinished() {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  if (mResult) {
-    // mRespondWithPromiseHolder should have been settled in
-    // {Resolve,Reject}Callback by now.
-    MOZ_DIAGNOSTIC_ASSERT(mRespondWithPromiseHolder.IsEmpty());
-
-    ServiceWorkerFetchEventOpResult result(
-        mResult.value() == Resolved ? NS_OK : NS_ERROR_FAILURE);
-
-    mPromiseHolder.Resolve(result, __func__);
-  }
-}
-
-bool FetchEventOp::Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) {
-  aWorkerPrivate->AssertIsOnWorkerThread();
-  MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-  MOZ_ASSERT(!mRespondWithPromiseHolder.IsEmpty());
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  nsresult rv = DispatchFetchEvent(aCx, aWorkerPrivate);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    RejectAll(rv);
-  }
-
-  return NS_SUCCEEDED(rv);
-}
-
-void FetchEventOp::AsyncLog(const nsCString& aMessageName,
-                            nsTArray<nsString> aParams) {
-  MOZ_ASSERT(mActor);
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-  MOZ_ASSERT(mRespondWithClosure);
-
-  const FetchEventRespondWithClosure& closure = mRespondWithClosure.ref();
-
-  AsyncLog(closure.respondWithScriptSpec(), closure.respondWithLineNumber(),
-           closure.respondWithColumnNumber(), aMessageName, std::move(aParams));
-}
-
-void FetchEventOp::AsyncLog(const nsCString& aScriptSpec, uint32_t aLineNumber,
-                            uint32_t aColumnNumber,
-                            const nsCString& aMessageName,
-                            nsTArray<nsString> aParams) {
-  MOZ_ASSERT(mActor);
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  // Capture `this` because FetchEventOpProxyChild (mActor) is not thread
-  // safe, so an AddRef from RefPtr<FetchEventOpProxyChild>'s constructor will
-  // assert.
-  RefPtr<FetchEventOp> self = this;
-
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-      __func__, [self = std::move(self), spec = aScriptSpec, line = aLineNumber,
-                 column = aColumnNumber, messageName = aMessageName,
-                 params = std::move(aParams)] {
-        if (NS_WARN_IF(!self->mActor)) {
-          return;
-        }
-
-        Unused << self->mActor->SendAsyncLog(spec, line, column, messageName,
-                                             params);
-      });
-
-  MOZ_ALWAYS_SUCCEEDS(
-      RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL));
-}
-
-void FetchEventOp::GetRequestURL(nsAString& aOutRequestURL) {
-  nsTArray<nsCString>& urls =
-      mArgs.get_ServiceWorkerFetchEventOpArgs().internalRequest().urlList();
-  MOZ_ASSERT(!urls.IsEmpty());
-
-  aOutRequestURL = NS_ConvertUTF8toUTF16(urls.LastElement());
-}
-
-void FetchEventOp::ResolvedCallback(JSContext* aCx,
-                                    JS::Handle<JS::Value> aValue) {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(mRespondWithClosure);
-  MOZ_ASSERT(!mRespondWithPromiseHolder.IsEmpty());
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  nsAutoString requestURL;
-  GetRequestURL(requestURL);
-
-  AutoCancel autoCancel(this);
-
-  if (!aValue.isObject()) {
-    NS_WARNING(
-        "FetchEvent::RespondWith was passed a promise resolved to a "
-        "non-Object "
-        "value");
-
-    nsCString sourceSpec;
-    uint32_t line = 0;
-    uint32_t column = 0;
-    nsString valueString;
-    nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column,
-                                       valueString);
-
-    autoCancel.SetCancelMessageAndLocation(
-        sourceSpec, line, column,
-        NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"), requestURL,
-        valueString);
-    return;
-  }
-
-  RefPtr<Response> response;
-  nsresult rv = UNWRAP_OBJECT(Response, &aValue.toObject(), response);
-  if (NS_FAILED(rv)) {
-    nsCString sourceSpec;
-    uint32_t line = 0;
-    uint32_t column = 0;
-    nsString valueString;
-    nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column,
-                                       valueString);
-
-    autoCancel.SetCancelMessageAndLocation(
-        sourceSpec, line, column,
-        NS_LITERAL_CSTRING("InterceptedNonResponseWithURL"), requestURL,
-        valueString);
-    return;
-  }
-
-  WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
-  MOZ_ASSERT(worker);
-  worker->AssertIsOnWorkerThread();
-
-  // Section "HTTP Fetch", step 3.3:
-  //  If one of the following conditions is true, return a network error:
-  //    * response's type is "error".
-  //    * request's mode is not "no-cors" and response's type is "opaque".
-  //    * request's redirect mode is not "manual" and response's type is
-  //      "opaqueredirect".
-  //    * request's redirect mode is not "follow" and response's url list
-  //      has more than one item.
-
-  if (response->Type() == ResponseType::Error) {
-    autoCancel.SetCancelMessage(
-        NS_LITERAL_CSTRING("InterceptedErrorResponseWithURL"), requestURL);
-    return;
-  }
-
-  const ServiceWorkerFetchEventOpArgs& args =
-      mArgs.get_ServiceWorkerFetchEventOpArgs();
-  const RequestMode requestMode = args.internalRequest().requestMode();
-
-  if (response->Type() == ResponseType::Opaque &&
-      requestMode != RequestMode::No_cors) {
-    uint32_t mode = static_cast<uint32_t>(requestMode);
-    NS_ConvertASCIItoUTF16 modeString(RequestModeValues::strings[mode].value,
-                                      RequestModeValues::strings[mode].length);
-
-    nsAutoString requestURL;
-    GetRequestURL(requestURL);
-
-    autoCancel.SetCancelMessage(
-        NS_LITERAL_CSTRING("BadOpaqueInterceptionRequestModeWithURL"),
-        requestURL, modeString);
-    return;
-  }
-
-  const RequestRedirect requestRedirectMode =
-      args.internalRequest().requestRedirect();
-
-  if (requestRedirectMode != RequestRedirect::Manual &&
-      response->Type() == ResponseType::Opaqueredirect) {
-    autoCancel.SetCancelMessage(
-        NS_LITERAL_CSTRING("BadOpaqueRedirectInterceptionWithURL"), requestURL);
-    return;
-  }
-
-  if (requestRedirectMode != RequestRedirect::Follow &&
-      response->Redirected()) {
-    autoCancel.SetCancelMessage(
-        NS_LITERAL_CSTRING("BadRedirectModeInterceptionWithURL"), requestURL);
-    return;
-  }
-
-  {
-    ErrorResult error;
-    bool bodyUsed = response->GetBodyUsed(error);
-    error.WouldReportJSException();
-    if (NS_WARN_IF(error.Failed())) {
-      autoCancel.SetCancelErrorResult(aCx, error);
-      return;
-    }
-    if (NS_WARN_IF(bodyUsed)) {
-      autoCancel.SetCancelMessage(
-          NS_LITERAL_CSTRING("InterceptedUsedResponseWithURL"), requestURL);
-      return;
-    }
-  }
-
-  RefPtr<InternalResponse> ir = response->GetInternalResponse();
-  if (NS_WARN_IF(!ir)) {
-    return;
-  }
-
-  // An extra safety check to make sure our invariant that opaque and cors
-  // responses always have a URL does not break.
-  if (NS_WARN_IF((response->Type() == ResponseType::Opaque ||
-                  response->Type() == ResponseType::Cors) &&
-                 ir->GetUnfilteredURL().IsEmpty())) {
-    MOZ_DIAGNOSTIC_ASSERT(false, "Cors or opaque Response without a URL");
-    return;
-  }
-
-  Telemetry::ScalarAdd(Telemetry::ScalarID::SW_SYNTHESIZED_RES_COUNT, 1);
-
-  if (requestMode == RequestMode::Same_origin &&
-      response->Type() == ResponseType::Cors) {
-    Telemetry::ScalarAdd(Telemetry::ScalarID::SW_CORS_RES_FOR_SO_REQ_COUNT, 1);
-
-    // XXXtt: Will have a pref to enable the quirk response in bug 1419684.
-    // The variadic template provided by StringArrayAppender requires exactly
-    // an nsString.
-    NS_ConvertUTF8toUTF16 responseURL(ir->GetUnfilteredURL());
-    autoCancel.SetCancelMessage(
-        NS_LITERAL_CSTRING("CorsResponseForSameOriginRequest"), requestURL,
-        responseURL);
-    return;
-  }
-
-  nsCOMPtr<nsIInputStream> body;
-  ir->GetUnfilteredBody(getter_AddRefs(body));
-  // Errors and redirects may not have a body.
-  if (body) {
-    ErrorResult error;
-    response->SetBodyUsed(aCx, error);
-    error.WouldReportJSException();
-    if (NS_WARN_IF(error.Failed())) {
-      autoCancel.SetCancelErrorResult(aCx, error);
-      return;
-    }
-  }
-
-  if (!ir->GetChannelInfo().IsInitialized()) {
-    // This is a synthetic response (I think and hope so).
-    ir->InitChannelInfo(worker->GetChannelInfo());
-  }
-
-  autoCancel.Reset();
-
-  mRespondWithPromiseHolder.Resolve(
-      FetchEventRespondWithResult(
-          SynthesizeResponseArgs(ir, mRespondWithClosure.ref())),
-      __func__);
-}
-
-void FetchEventOp::RejectedCallback(JSContext* aCx,
-                                    JS::Handle<JS::Value> aValue) {
-  MOZ_ASSERT(IsCurrentThreadRunningWorker());
-  MOZ_ASSERT(mRespondWithClosure);
-  MOZ_ASSERT(!mRespondWithPromiseHolder.IsEmpty());
-  MOZ_ASSERT(!mPromiseHolder.IsEmpty());
-
-  FetchEventRespondWithClosure& closure = mRespondWithClosure.ref();
-
-  nsCString sourceSpec = closure.respondWithScriptSpec();
-  uint32_t line = closure.respondWithLineNumber();
-  uint32_t column = closure.respondWithColumnNumber();
-  nsString valueString;
-
-  nsContentUtils::ExtractErrorValues(aCx, aValue, sourceSpec, &line, &column,
-                                     valueString);
-
-  nsString requestURL;
-  GetRequestURL(requestURL);
-
-  AsyncLog(sourceSpec, line, column,
-           NS_LITERAL_CSTRING("InterceptionRejectedResponseWithURL"),
-           {std::move(requestURL), valueString});
-
-  mRespondWithPromiseHolder.Resolve(
-      FetchEventRespondWithResult(
-          CancelInterceptionArgs(NS_ERROR_INTERCEPTION_FAILED)),
-      __func__);
-}
-
-nsresult FetchEventOp::DispatchFetchEvent(JSContext* aCx,
-                                          WorkerPrivate* aWorkerPrivate) {
-  MOZ_ASSERT(aCx);
-  MOZ_ASSERT(aWorkerPrivate);
-  aWorkerPrivate->AssertIsOnWorkerThread();
-  MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
-
-  ServiceWorkerFetchEventOpArgs& args =
-      mArgs.get_ServiceWorkerFetchEventOpArgs();
-
-  /**
-   * Step 1: get the InternalRequest. The InternalRequest can't be constructed
-   * here from mArgs because the IPCStream has to be deserialized on the
-   * thread receiving the ServiceWorkerFetchEventOpArgs.
-   * FetchEventOpProxyChild will have already deserialized the stream on the
-   * correct thread before creating this op, so we can take its saved
-   * InternalRequest.
-   */
-  RefPtr<InternalRequest> internalRequest = mActor->ExtractInternalRequest();
-
-  /**
-   * Step 2: get the worker's global object
-   */
-  GlobalObject globalObject(aCx, aWorkerPrivate->GlobalScope()->GetWrapper());
-  nsCOMPtr<nsIGlobalObject> globalObjectAsSupports =
-      do_QueryInterface(globalObject.GetAsSupports());
-  if (NS_WARN_IF(!globalObjectAsSupports)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  /**
-   * Step 3: create the public DOM Request object
-   * TODO: this Request object should be created with an AbortSignal object
-   * which should be aborted if the loading is aborted. See but 1394102.
-   */
-  RefPtr<Request> request =
-      new Request(globalObjectAsSupports, internalRequest, nullptr);
-  MOZ_ASSERT_IF(internalRequest->IsNavigationRequest(),
-                request->Redirect() == RequestRedirect::Manual);
-
-  /**
-   * Step 4a: create the FetchEventInit
-   */
-  RootedDictionary<FetchEventInit> fetchEventInit(aCx);
-  fetchEventInit.mRequest = request;
-  fetchEventInit.mBubbles = false;
-  fetchEventInit.mCancelable = true;
-  fetchEventInit.mIsReload = args.isReload();
-
-  /**
-   * TODO: only expose the FetchEvent.clientId on subresource requests for
-   * now. Once we implement .targetClientId we can then start exposing
-   * .clientId on non-subresource requests as well.  See bug 1487534.
-   */
-  if (!args.clientId().IsEmpty() && !internalRequest->IsNavigationRequest()) {
-    fetchEventInit.mClientId = args.clientId();
-  }
-
-  /*
-   * https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm
-   *
-   * "If request is a non-subresource request and request’s
-   * destination is not "report", initialize e’s resultingClientId attribute
-   * to reservedClient’s [resultingClient's] id, and to the empty string
-   * otherwise." (Step 18.8)
-   */
-  if (!args.resultingClientId().IsEmpty() && args.isNonSubresourceRequest() &&
-      internalRequest->Destination() != RequestDestination::Report) {
-    fetchEventInit.mResultingClientId = args.resultingClientId();
-  }
-
-  /**
-   * Step 4b: create the FetchEvent
-   */
-  ErrorResult result;
-  RefPtr<FetchEvent> fetchEvent = FetchEvent::Constructor(
-      globalObject, NS_LITERAL_STRING("fetch"), fetchEventInit, result);
-  if (NS_WARN_IF(result.Failed())) {
-    return result.StealNSResult();
-  }
-  fetchEvent->SetTrusted(true);
-  fetchEvent->PostInit(args.workerScriptSpec(), this);
-
-  /**
-   * Step 5: Dispatch the FetchEvent to the worker's global object
-   */
-  nsresult rv = DispatchExtendableEventOnWorkerScope(
-      aCx, aWorkerPrivate->GlobalScope(), fetchEvent, this);
-  bool dispatchFailed = NS_FAILED(rv) && rv != NS_ERROR_XPC_JS_THREW_EXCEPTION;
-
-  if (NS_WARN_IF(dispatchFailed)) {
-    return rv;
-  }
-
-  /**
-   * At this point, there are 4 (legal) scenarios:
-   *
-   * 1) If neither waitUntil() nor respondWith() are called,
-   * DispatchExtendableEventOnWorkerScope() will have already called
-   * FinishedWithResult(), but this call will have recorded the result
-   * (mResult) and returned early so that mRespondWithPromiseHolder can be
-   * settled first. mRespondWithPromiseHolder will be settled below, followed
-   * by a call to MaybeFinished() which settles mPromiseHolder.
-   *
-   * 2) If waitUntil() is called at least once, and respondWith() is not
-   * called, DispatchExtendableEventOnWorkerScope() will NOT have called
-   * FinishedWithResult(). We'll settle mRespondWithPromiseHolder first, and
-   * at some point in the future when the last waitUntil() promise settles,
-   * FinishedWithResult() will be called, settling mPromiseHolder.
-   *
-   * 3) If waitUntil() is not called, and respondWith() is called,
-   * DispatchExtendableEventOnWorkerScope() will NOT have called
-   * FinishedWithResult(). We can also guarantee that
-   * mRespondWithPromiseHolder will be settled before mPromiseHolder, due to
-   * the Promise::AppendNativeHandler() call ordering in
-   * FetchEvent::RespondWith().
-   *
-   * 4) If waitUntil() is called at least once, and respondWith() is also
-   * called, the effect is similar to scenario 3), with the most imporant
-   * property being mRespondWithPromiseHolder settling before mPromiseHolder.
-   *
-   * Note that if mPromiseHolder is settled before mRespondWithPromiseHolder,
-   * FetchEventOpChild will cancel the interception.
-   */
-  if (!fetchEvent->WaitToRespond()) {
-    MOZ_ASSERT(!mRespondWithPromiseHolder.IsEmpty());
-    MOZ_ASSERT(!aWorkerPrivate->UsesSystemPrincipal(),
-               "We don't support system-principal serviceworkers");
-
-    if (fetchEvent->DefaultPrevented(CallerType::NonSystem)) {
-      mRespondWithPromiseHolder.Resolve(
-          FetchEventRespondWithResult(
-              CancelInterceptionArgs(NS_ERROR_INTERCEPTION_FAILED)),
-          __func__);
-    } else {
-      mRespondWithPromiseHolder.Resolve(
-          FetchEventRespondWithResult(ResetInterceptionArgs()), __func__);
-    }
-  } else {
-    MOZ_ASSERT(mRespondWithClosure);
-  }
-
-  mPostDispatchChecksDone = true;
-  MaybeFinished();
-
-  return NS_OK;
-}
-
-/* static */ already_AddRefed<ServiceWorkerOp> ServiceWorkerOp::Create(
-    const ServiceWorkerOpArgs& aArgs,
-    std::function<void(const ServiceWorkerOpResult&)>&& aCallback) {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-
-  RefPtr<ServiceWorkerOp> op;
-
-  switch (aArgs.type()) {
-    case ServiceWorkerOpArgs::TServiceWorkerCheckScriptEvaluationOpArgs:
-      op = MakeRefPtr<CheckScriptEvaluationOp>(aArgs, std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerUpdateStateOpArgs:
-      op = MakeRefPtr<UpdateServiceWorkerStateOp>(aArgs, std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerTerminateWorkerOpArgs:
-      op = MakeRefPtr<TerminateServiceWorkerOp>(aArgs, std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerLifeCycleEventOpArgs:
-      op = MakeRefPtr<LifeCycleEventOp>(aArgs, std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerPushEventOpArgs:
-      op = MakeRefPtr<PushEventOp>(aArgs, std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerPushSubscriptionChangeEventOpArgs:
-      op = MakeRefPtr<PushSubscriptionChangeEventOp>(aArgs,
-                                                     std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerNotificationEventOpArgs:
-      op = MakeRefPtr<NotificationEventOp>(aArgs, std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerMessageEventOpArgs:
-      op = MakeRefPtr<MessageEventOp>(aArgs, std::move(aCallback));
-      break;
-    case ServiceWorkerOpArgs::TServiceWorkerFetchEventOpArgs:
-      op = MakeRefPtr<FetchEventOp>(aArgs, std::move(aCallback));
-      break;
-    default:
-      MOZ_CRASH("Unknown Service Worker operation!");
-      return nullptr;
-  }
-
-  return op.forget();
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerOp.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_serviceworkerop_h__
-#define mozilla_dom_serviceworkerop_h__
-
-#include <functional>
-
-#include "nsISupportsImpl.h"
-
-#include "ServiceWorkerEvents.h"
-#include "ServiceWorkerOpPromise.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/Maybe.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/dom/PromiseNativeHandler.h"
-#include "mozilla/dom/RemoteWorkerChild.h"
-#include "mozilla/dom/ServiceWorkerOpArgs.h"
-#include "mozilla/dom/WorkerRunnable.h"
-
-namespace mozilla {
-namespace dom {
-
-class FetchEventOpProxyChild;
-
-class ServiceWorkerOp : public RemoteWorkerChild::Op {
- public:
-  // `aCallback` will be called when the operation completes or is canceled.
-  static already_AddRefed<ServiceWorkerOp> Create(
-      const ServiceWorkerOpArgs& aArgs,
-      std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
-
-  ServiceWorkerOp(
-      const ServiceWorkerOpArgs& aArgs,
-      std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
-
-  ServiceWorkerOp(const ServiceWorkerOp&) = delete;
-
-  ServiceWorkerOp& operator=(const ServiceWorkerOp&) = delete;
-
-  ServiceWorkerOp(ServiceWorkerOp&&) = default;
-
-  ServiceWorkerOp& operator=(ServiceWorkerOp&&) = default;
-
-  // Returns `true` if the operation has started and `false` otherwise.
-  bool MaybeStart(RemoteWorkerChild* aOwner,
-                  RemoteWorkerChild::State& aState) final;
-
-  void Cancel() final;
-
- protected:
-  ~ServiceWorkerOp();
-
-  bool Started() const;
-
-  bool IsTerminationOp() const;
-
-  // Override to provide a runnable that's not a `ServiceWorkerOpRunnable.`
-  virtual RefPtr<WorkerRunnable> GetRunnable(WorkerPrivate* aWorkerPrivate);
-
-  virtual bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
-
-  // Override to reject any additional MozPromises that subclasses may contain.
-  virtual void RejectAll(nsresult aStatus);
-
-  ServiceWorkerOpArgs mArgs;
-
-  // Subclasses must settle this promise when appropriate.
-  MozPromiseHolder<ServiceWorkerOpPromise> mPromiseHolder;
-
- private:
-  class ServiceWorkerOpRunnable;
-
-  bool mStarted = false;
-};
-
-class ExtendableEventOp : public ServiceWorkerOp,
-                          public ExtendableEventCallback {
-  using ServiceWorkerOp::ServiceWorkerOp;
-
- protected:
-  ~ExtendableEventOp() = default;
-
-  void FinishedWithResult(ExtendableEventResult aResult) override;
-};
-
-class FetchEventOp final : public ExtendableEventOp,
-                           public PromiseNativeHandler {
-  using ExtendableEventOp::ExtendableEventOp;
-
- public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-
-  /**
-   * This must be called once and only once before the first call to
-   * `MaybeStart()`; `aActor` will be used for `AsyncLog()` and
-   * `ReportCanceled().`
-   */
-  void SetActor(RefPtr<FetchEventOpProxyChild> aActor);
-
-  void RevokeActor(FetchEventOpProxyChild* aActor);
-
-  // This must be called at most once before the first call to `MaybeStart().`
-  RefPtr<FetchEventRespondWithPromise> GetRespondWithPromise();
-
-  // This must be called when `FetchEvent::RespondWith()` is called.
-  void RespondWithCalledAt(const nsCString& aRespondWithScriptSpec,
-                           uint32_t aRespondWithLineNumber,
-                           uint32_t aRespondWithColumnNumber);
-
-  void ReportCanceled(const nsCString& aPreventDefaultScriptSpec,
-                      uint32_t aPreventDefaultLineNumber,
-                      uint32_t aPreventDefaultColumnNumber);
-
- private:
-  class AutoCancel;
-
-  ~FetchEventOp();
-
-  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
-
-  void RejectAll(nsresult aStatus) override;
-
-  void FinishedWithResult(ExtendableEventResult aResult) override;
-
-  /**
-   * `{Resolved,Reject}Callback()` are use to handle the
-   * `FetchEvent::RespondWith()` promise.
-   */
-  void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
-
-  void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
-
-  void MaybeFinished();
-
-  // Requires mRespondWithClosure to be non-empty.
-  void AsyncLog(const nsCString& aMessageName, nsTArray<nsString> aParams);
-
-  void AsyncLog(const nsCString& aScriptSpec, uint32_t aLineNumber,
-                uint32_t aColumnNumber, const nsCString& aMessageName,
-                nsTArray<nsString> aParams);
-
-  void GetRequestURL(nsAString& aOutRequestURL);
-
-  // A failure code means that the dispatch failed.
-  nsresult DispatchFetchEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
-
-  // Worker Launcher thread only. Used for `AsyncLog().`
-  RefPtr<FetchEventOpProxyChild> mActor;
-
-  /**
-   * Created on the Worker Launcher thread and settled on the worker thread.
-   * If this isn't settled before `mPromiseHolder` (which it should be),
-   * `FetchEventOpChild` will cancel the intercepted network request.
-   */
-  MozPromiseHolder<FetchEventRespondWithPromise> mRespondWithPromiseHolder;
-
-  // Worker thread only.
-  Maybe<ExtendableEventResult> mResult;
-  bool mPostDispatchChecksDone = false;
-
-  // Worker thread only; set when `FetchEvent::RespondWith()` is called.
-  Maybe<FetchEventRespondWithClosure> mRespondWithClosure;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_serviceworkerop_h__
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerOpArgs.ipdlh
+++ /dev/null
@@ -1,129 +0,0 @@
-/* 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 ChannelInfo;
-include ClientIPCTypes;
-include DOMTypes;
-include FetchTypes;
-
-using ServiceWorkerState from "mozilla/dom/ServiceWorkerIPCUtils.h";
-
-namespace mozilla {
-namespace dom {
-
-/**
- * ServiceWorkerOpArgs
- */
-struct ServiceWorkerCheckScriptEvaluationOpArgs {};
-
-struct ServiceWorkerUpdateStateOpArgs {
-  ServiceWorkerState state;
-};
-
-struct ServiceWorkerTerminateWorkerOpArgs {};
-
-struct ServiceWorkerLifeCycleEventOpArgs {
-  nsString eventName;
-};
-
-// Possibly need to differentiate an empty array from the absence of an array.
-union OptionalPushData {
-  void_t;
-  uint8_t[];
-};
-
-struct ServiceWorkerPushEventOpArgs {
-  nsString messageId;
-  OptionalPushData data;
-};
-
-struct ServiceWorkerPushSubscriptionChangeEventOpArgs {};
-
-struct ServiceWorkerNotificationEventOpArgs {
-  nsString eventName;
-  nsString id;
-  nsString title;
-  nsString dir;
-  nsString lang;
-  nsString body;
-  nsString tag;
-  nsString icon;
-  nsString data;
-  nsString behavior;
-  nsString scope;
-  uint32_t disableOpenClickDelay;
-};
-
-struct ServiceWorkerMessageEventOpArgs {
-  ClientInfoAndState clientInfoAndState;
-  ClonedMessageData clonedData;
-};
-
-struct ServiceWorkerFetchEventOpArgs {
-  nsCString workerScriptSpec;
-  IPCInternalRequest internalRequest;
-  nsString clientId;
-  nsString resultingClientId;
-  bool isReload;
-  bool isNonSubresourceRequest;
-};
-
-union ServiceWorkerOpArgs {
-  ServiceWorkerCheckScriptEvaluationOpArgs;
-  ServiceWorkerUpdateStateOpArgs;
-  ServiceWorkerTerminateWorkerOpArgs;
-  ServiceWorkerLifeCycleEventOpArgs;
-  ServiceWorkerPushEventOpArgs;
-  ServiceWorkerPushSubscriptionChangeEventOpArgs;
-  ServiceWorkerNotificationEventOpArgs;
-  ServiceWorkerMessageEventOpArgs;
-  ServiceWorkerFetchEventOpArgs;
-};
-
-/**
- * IPCFetchEventRespondWithResult
- */
-struct FetchEventRespondWithClosure {
-  nsCString respondWithScriptSpec;
-  uint32_t respondWithLineNumber;
-  uint32_t respondWithColumnNumber;
-};
-
-struct IPCSynthesizeResponseArgs {
-  IPCInternalResponse internalResponse;
-  FetchEventRespondWithClosure closure;
-};
-
-struct ResetInterceptionArgs {};
-
-struct CancelInterceptionArgs {
-  nsresult status;
-};
-
-union IPCFetchEventRespondWithResult {
-  IPCSynthesizeResponseArgs;
-  ResetInterceptionArgs;
-  CancelInterceptionArgs;
-};
-
-/**
- * ServiceWorkerOpResult
- */
-struct ServiceWorkerCheckScriptEvaluationOpResult {
-  bool workerScriptExecutedSuccessfully;
-  bool fetchHandlerWasAdded;
-};
-
-struct ServiceWorkerFetchEventOpResult {
-  nsresult rv;
-};
-
-union ServiceWorkerOpResult {
-  nsresult;
-  ServiceWorkerCheckScriptEvaluationOpResult;
-  ServiceWorkerFetchEventOpResult;
-};
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerOpPromise.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_serviceworkeroppromise_h__
-#define mozilla_dom_serviceworkeroppromise_h__
-
-#include "mozilla/MozPromise.h"
-#include "mozilla/Pair.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/dom/ServiceWorkerOpArgs.h"
-
-namespace mozilla {
-namespace dom {
-
-class InternalResponse;
-
-using SynthesizeResponseArgs =
-    Pair<RefPtr<InternalResponse>, FetchEventRespondWithClosure>;
-
-using FetchEventRespondWithResult =
-    Variant<SynthesizeResponseArgs, ResetInterceptionArgs,
-            CancelInterceptionArgs>;
-
-using FetchEventRespondWithPromise =
-    MozPromise<FetchEventRespondWithResult, nsresult, true>;
-
-using ServiceWorkerOpPromise =
-    MozPromise<ServiceWorkerOpResult, nsresult, true>;
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_serviceworkeroppromise_h__
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -1,22 +1,18 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "ServiceWorkerPrivate.h"
 
-#include <utility>
-
 #include "ServiceWorkerCloneData.h"
 #include "ServiceWorkerManager.h"
-#include "ServiceWorkerPrivateImpl.h"
-#include "ServiceWorkerUtils.h"
 #include "nsContentUtils.h"
 #include "nsICacheInfoChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsINamed.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIPushErrorReporter.h"
 #include "nsISupportsImpl.h"
@@ -39,20 +35,18 @@
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/dom/PushEventBinding.h"
 #include "mozilla/dom/RequestBinding.h"
 #include "mozilla/dom/WorkerDebugger.h"
 #include "mozilla/dom/WorkerRef.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/dom/WorkerScope.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
-#include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/net/CookieSettings.h"
 #include "mozilla/net/NeckoChannelParams.h"
-#include "mozilla/Services.h"
 #include "mozilla/StaticPrefs_dom.h"
 #include "mozilla/Unused.h"
 #include "nsIReferrerInfo.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 namespace mozilla {
@@ -69,51 +63,51 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(S
 // Tracks the "dom.serviceWorkers.disable_open_click_delay" preference. Modified
 // on main thread, read on worker threads.
 // It is updated every time a "notificationclick" event is dispatched. While
 // this is done without synchronization, at the worst, the thread will just get
 // an older value within which a popup is allowed to be displayed, which will
 // still be a valid value since it was set prior to dispatching the runnable.
 Atomic<uint32_t> gDOMDisableOpenClickDelay(0);
 
-KeepAliveToken::KeepAliveToken(ServiceWorkerPrivate* aPrivate)
-    : mPrivate(aPrivate) {
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aPrivate);
-  mPrivate->AddToken();
-}
+// Used to keep track of pending waitUntil as well as in-flight extendable
+// events. When the last token is released, we attempt to terminate the worker.
+class KeepAliveToken final : public nsISupports {
+ public:
+  NS_DECL_ISUPPORTS
 
-KeepAliveToken::~KeepAliveToken() {
-  MOZ_ASSERT(NS_IsMainThread());
-  mPrivate->ReleaseToken();
-}
+  explicit KeepAliveToken(ServiceWorkerPrivate* aPrivate) : mPrivate(aPrivate) {
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(aPrivate);
+    mPrivate->AddToken();
+  }
+
+ private:
+  ~KeepAliveToken() {
+    MOZ_ASSERT(NS_IsMainThread());
+    mPrivate->ReleaseToken();
+  }
+
+  RefPtr<ServiceWorkerPrivate> mPrivate;
+};
 
 NS_IMPL_ISUPPORTS0(KeepAliveToken)
 
 ServiceWorkerPrivate::ServiceWorkerPrivate(ServiceWorkerInfo* aInfo)
     : mInfo(aInfo), mDebuggerCount(0), mTokenCount(0) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aInfo);
 
   mIdleWorkerTimer = NS_NewTimer();
   MOZ_ASSERT(mIdleWorkerTimer);
-
-  if (ServiceWorkerParentInterceptEnabled()) {
-    RefPtr<ServiceWorkerPrivateImpl> inner = new ServiceWorkerPrivateImpl(this);
-    nsresult rv = inner->Initialize();
-    MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
-
-    mInner = inner.forget();
-  }
 }
 
 ServiceWorkerPrivate::~ServiceWorkerPrivate() {
   MOZ_ASSERT(!mWorkerPrivate);
   MOZ_ASSERT(!mTokenCount);
-  MOZ_ASSERT(!mInner);
   MOZ_ASSERT(!mInfo);
   MOZ_ASSERT(mSupportsArray.IsEmpty());
   MOZ_ASSERT(mIdlePromiseHolder.IsEmpty());
 
   mIdleWorkerTimer->Cancel();
 }
 
 namespace {
@@ -190,37 +184,40 @@ class CheckScriptEvaluationWithCallback 
         mWorkerPrivate->DispatchToMainThread(mScriptEvaluationCallback));
   }
 };
 
 }  // anonymous namespace
 
 nsresult ServiceWorkerPrivate::CheckScriptEvaluation(
     LifeCycleEventCallback* aScriptEvaluationCallback) {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mInner) {
-    return mInner->CheckScriptEvaluation(aScriptEvaluationCallback);
-  }
-
   nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
   RefPtr<WorkerRunnable> r = new CheckScriptEvaluationWithCallback(
       mWorkerPrivate, this, token, aScriptEvaluationCallback);
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 namespace {
 
+enum ExtendableEventResult { Rejected = 0, Resolved };
+
+class ExtendableEventCallback {
+ public:
+  virtual void FinishedWithResult(ExtendableEventResult aResult) = 0;
+
+  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+};
+
 class KeepAliveHandler final : public ExtendableEvent::ExtensionsHandler,
                                public PromiseNativeHandler {
   // This class manages lifetime extensions added by calling WaitUntil()
   // or RespondWith(). We allow new extensions as long as we still hold
   // |mKeepAliveToken|. Once the last promise was settled, we queue a microtask
   // which releases the token and prevents further extensions. By doing this,
   // we give other pending microtasks a chance to continue adding extensions.
 
@@ -514,20 +511,16 @@ class SendMessageEventRunnable final : p
 
 }  // anonymous namespace
 
 nsresult ServiceWorkerPrivate::SendMessageEvent(
     RefPtr<ServiceWorkerCloneData>&& aData,
     const ClientInfoAndState& aClientInfoAndState) {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mInner) {
-    return mInner->SendMessageEvent(std::move(aData), aClientInfoAndState);
-  }
-
   nsresult rv = SpawnWorkerIfNeeded(MessageEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
   RefPtr<SendMessageEventRunnable> runnable = new SendMessageEventRunnable(
       mWorkerPrivate, token, aClientInfoAndState, std::move(aData));
 
   if (!runnable->Dispatch()) {
@@ -726,22 +719,16 @@ bool LifecycleEventWorkerRunnable::Dispa
 
   return true;
 }
 
 }  // anonymous namespace
 
 nsresult ServiceWorkerPrivate::SendLifeCycleEvent(
     const nsAString& aEventType, LifeCycleEventCallback* aCallback) {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mInner) {
-    return mInner->SendLifeCycleEvent(aEventType, aCallback);
-  }
-
   nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
   RefPtr<WorkerRunnable> r = new LifecycleEventWorkerRunnable(
       mWorkerPrivate, token, aEventType, aCallback);
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
@@ -892,22 +879,16 @@ class SendPushSubscriptionChangeEventRun
   }
 };
 
 }  // anonymous namespace
 
 nsresult ServiceWorkerPrivate::SendPushEvent(
     const nsAString& aMessageId, const Maybe<nsTArray<uint8_t>>& aData,
     ServiceWorkerRegistrationInfo* aRegistration) {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mInner) {
-    return mInner->SendPushEvent(aRegistration, aMessageId, aData);
-  }
-
   nsresult rv = SpawnWorkerIfNeeded(PushEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
 
   nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> regInfo(
       new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(
           "ServiceWorkerRegistrationInfoProxy", aRegistration, false));
@@ -925,22 +906,16 @@ nsresult ServiceWorkerPrivate::SendPushE
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult ServiceWorkerPrivate::SendPushSubscriptionChangeEvent() {
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mInner) {
-    return mInner->SendPushSubscriptionChangeEvent();
-  }
-
   nsresult rv = SpawnWorkerIfNeeded(PushSubscriptionChangeEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
   RefPtr<WorkerRunnable> r =
       new SendPushSubscriptionChangeEventRunnable(mWorkerPrivate, token);
   if (NS_WARN_IF(!r->Dispatch())) {
     return NS_ERROR_FAILURE;
@@ -1146,36 +1121,28 @@ class SendNotificationEventRunnable fina
 
 }  // namespace
 
 nsresult ServiceWorkerPrivate::SendNotificationEvent(
     const nsAString& aEventName, const nsAString& aID, const nsAString& aTitle,
     const nsAString& aDir, const nsAString& aLang, const nsAString& aBody,
     const nsAString& aTag, const nsAString& aIcon, const nsAString& aData,
     const nsAString& aBehavior, const nsAString& aScope) {
-  MOZ_ASSERT(NS_IsMainThread());
-
   WakeUpReason why;
   if (aEventName.EqualsLiteral(NOTIFICATION_CLICK_EVENT_NAME)) {
     why = NotificationClickEvent;
     gDOMDisableOpenClickDelay =
         Preferences::GetInt("dom.serviceWorkers.disable_open_click_delay");
   } else if (aEventName.EqualsLiteral(NOTIFICATION_CLOSE_EVENT_NAME)) {
     why = NotificationCloseEvent;
   } else {
     MOZ_ASSERT_UNREACHABLE("Invalid notification event name");
     return NS_ERROR_FAILURE;
   }
 
-  if (mInner) {
-    return mInner->SendNotificationEvent(aEventName, aID, aTitle, aDir, aLang,
-                                         aBody, aTag, aIcon, aData, aBehavior,
-                                         aScope, gDOMDisableOpenClickDelay);
-  }
-
   nsresult rv = SpawnWorkerIfNeeded(why);
   NS_ENSURE_SUCCESS(rv, rv);
 
   RefPtr<KeepAliveToken> token = CreateEventKeepAliveToken();
 
   RefPtr<WorkerRunnable> r = new SendNotificationEventRunnable(
       mWorkerPrivate, token, aEventName, aID, aTitle, aDir, aLang, aBody, aTag,
       aIcon, aData, aBehavior, aScope);
@@ -1615,21 +1582,16 @@ nsresult ServiceWorkerPrivate::SendFetch
     }
 
     // Trigger soft updates if necessary.
     registration->MaybeScheduleTimeCheckAndUpdate();
 
     return NS_OK;
   }
 
-  if (mInner) {
-    return mInner->SendFetchEvent(std::move(registration), aChannel, aClientId,
-                                  aResultingClientId, aIsReload);
-  }
-
   aChannel->SetLaunchServiceWorkerStart(TimeStamp::Now());
   aChannel->SetDispatchFetchEventStart(TimeStamp::Now());
 
   bool newWorkerCreated = false;
   rv = SpawnWorkerIfNeeded(FetchEvent, &newWorkerCreated, aLoadGroup);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!newWorkerCreated) {
@@ -1667,17 +1629,16 @@ nsresult ServiceWorkerPrivate::SendFetch
 
   return NS_OK;
 }
 
 nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
                                                    bool* aNewWorkerCreated,
                                                    nsILoadGroup* aLoadGroup) {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(!mInner);
 
   // Defaults to no new worker created, but if there is one, we'll set the value
   // to true at the end of this function.
   if (aNewWorkerCreated) {
     *aNewWorkerCreated = false;
   }
 
   // If the worker started shutting down on itself we may have a stale
@@ -1824,20 +1785,16 @@ bool ServiceWorkerPrivate::MaybeStoreISu
 void ServiceWorkerPrivate::RemoveISupports(nsISupports* aSupports) {
   MOZ_ASSERT(NS_IsMainThread());
   mSupportsArray.RemoveElement(aSupports);
 }
 
 void ServiceWorkerPrivate::TerminateWorker() {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mInner) {
-    return mInner->TerminateWorker();
-  }
-
   mIdleWorkerTimer->Cancel();
   mIdleKeepAliveToken = nullptr;
   if (mWorkerPrivate) {
     if (StaticPrefs::dom_serviceWorkers_testing_enabled()) {
       nsCOMPtr<nsIObserverService> os = services::GetObserverService();
       if (os) {
         os->NotifyObservers(nullptr, "service-worker-shutdown", nullptr);
       }
@@ -1855,25 +1812,18 @@ void ServiceWorkerPrivate::TerminateWork
     for (uint32_t i = 0; i < pendingEvents.Length(); ++i) {
       pendingEvents[i]->Cancel();
     }
   }
 }
 
 void ServiceWorkerPrivate::NoteDeadServiceWorkerInfo() {
   MOZ_ASSERT(NS_IsMainThread());
-
-  if (mInner) {
-    mInner->NoteDeadOuter();
-    mInner = nullptr;
-  } else {
-    TerminateWorker();
-  }
-
   mInfo = nullptr;
+  TerminateWorker();
 }
 
 namespace {
 
 class UpdateStateControlRunnable final
     : public MainThreadWorkerControlRunnable {
   const ServiceWorkerState mState;
 
@@ -1889,20 +1839,16 @@ class UpdateStateControlRunnable final
       : MainThreadWorkerControlRunnable(aWorkerPrivate), mState(aState) {}
 };
 
 }  // anonymous namespace
 
 void ServiceWorkerPrivate::UpdateState(ServiceWorkerState aState) {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mInner) {
-    return mInner->UpdateState(aState);
-  }
-
   if (!mWorkerPrivate) {
     MOZ_DIAGNOSTIC_ASSERT(mPendingFunctionalEvents.IsEmpty());
     return;
   }
 
   RefPtr<WorkerRunnable> r =
       new UpdateStateControlRunnable(mWorkerPrivate, aState);
   Unused << r->Dispatch();
@@ -1921,40 +1867,31 @@ void ServiceWorkerPrivate::UpdateState(S
     }
   }
 }
 
 nsresult ServiceWorkerPrivate::GetDebugger(nsIWorkerDebugger** aResult) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aResult);
 
-  if (mInner) {
-    *aResult = nullptr;
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
   if (!mDebuggerCount) {
     return NS_OK;
   }
 
   MOZ_ASSERT(mWorkerPrivate);
 
   nsCOMPtr<nsIWorkerDebugger> debugger = mWorkerPrivate->Debugger();
   debugger.forget(aResult);
 
   return NS_OK;
 }
 
 nsresult ServiceWorkerPrivate::AttachDebugger() {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mInner) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
   // When the first debugger attaches to a worker, we spawn a worker if needed,
   // and cancel the idle timeout. The idle timeout should not be reset until
   // the last debugger detached from the worker.
   if (!mDebuggerCount) {
     nsresult rv = SpawnWorkerIfNeeded(AttachEvent);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mIdleWorkerTimer->Cancel();
@@ -1963,20 +1900,16 @@ nsresult ServiceWorkerPrivate::AttachDeb
   ++mDebuggerCount;
 
   return NS_OK;
 }
 
 nsresult ServiceWorkerPrivate::DetachDebugger() {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mInner) {
-    return NS_ERROR_NOT_IMPLEMENTED;
-  }
-
   if (!mDebuggerCount) {
     return NS_ERROR_UNEXPECTED;
   }
 
   --mDebuggerCount;
 
   // When the last debugger detaches from a worker, we either reset the idle
   // timeout, or terminate the worker if there are no more active tokens.
@@ -2048,20 +1981,17 @@ NS_IMPL_ISUPPORTS(ServiceWorkerPrivateTi
 void ServiceWorkerPrivate::NoteIdleWorkerCallback(nsITimer* aTimer) {
   MOZ_ASSERT(NS_IsMainThread());
 
   MOZ_ASSERT(aTimer == mIdleWorkerTimer, "Invalid timer!");
 
   // Release ServiceWorkerPrivate's token, since the grace period has ended.
   mIdleKeepAliveToken = nullptr;
 
-  if (mWorkerPrivate || (mInner && !mInner->WorkerIsDead())) {
-    // There sould only be EITHER mWorkerPrivate or mInner (but not both).
-    MOZ_ASSERT(!(mWorkerPrivate && mInner));
-
+  if (mWorkerPrivate) {
     // If we still have a workerPrivate at this point it means there are pending
     // waitUntil promises. Wait a bit more until we forcibly terminate the
     // worker.
     uint32_t timeout =
         Preferences::GetInt("dom.serviceWorkers.idle_extended_timeout");
     nsCOMPtr<nsITimerCallback> cb = new ServiceWorkerPrivateTimerCallback(
         this, &ServiceWorkerPrivate::TerminateWorkerCallback);
     DebugOnly<nsresult> rv = mIdleWorkerTimer->InitWithCallback(
@@ -2082,17 +2012,17 @@ void ServiceWorkerPrivate::TerminateWork
       mInfo->Scope(), "ServiceWorkerGraceTimeoutTermination",
       nsTArray<nsString>{NS_ConvertUTF8toUTF16(mInfo->Scope())});
 
   TerminateWorker();
 }
 
 void ServiceWorkerPrivate::RenewKeepAliveToken(WakeUpReason aWhy) {
   // We should have an active worker if we're renewing the keep alive token.
-  MOZ_ASSERT(mWorkerPrivate || (mInner && !mInner->WorkerIsDead()));
+  MOZ_ASSERT(mWorkerPrivate);
 
   // If there is at least one debugger attached to the worker, the idle worker
   // timeout was canceled when the first debugger attached to the worker. It
   // should not be reset until the last debugger detaches from the worker.
   if (!mDebuggerCount) {
     ResetIdleTimeout();
   }
 
@@ -2137,23 +2067,18 @@ void ServiceWorkerPrivate::ReleaseToken(
       }
     }
   }
 }
 
 already_AddRefed<KeepAliveToken>
 ServiceWorkerPrivate::CreateEventKeepAliveToken() {
   MOZ_ASSERT(NS_IsMainThread());
-
-  // When the WorkerPrivate is in a separate process, we first hold a normal
-  // KeepAliveToken. Then, after we're notified that the worker is alive, we
-  // create the idle KeepAliveToken.
-  MOZ_ASSERT(mWorkerPrivate || (mInner && !mInner->WorkerIsDead()));
-  MOZ_ASSERT(mIdleKeepAliveToken || (mInner && !mInner->WorkerIsDead()));
-
+  MOZ_ASSERT(mWorkerPrivate);
+  MOZ_ASSERT(mIdleKeepAliveToken);
   RefPtr<KeepAliveToken> ref = new KeepAliveToken(this);
   return ref.forget();
 }
 
 void ServiceWorkerPrivate::SetHandlesFetch(bool aValue) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (NS_WARN_IF(!mInfo)) {
--- a/dom/serviceworkers/ServiceWorkerPrivate.h
+++ b/dom/serviceworkers/ServiceWorkerPrivate.h
@@ -19,48 +19,33 @@ class nsIWorkerDebugger;
 
 namespace mozilla {
 
 class JSObjectHolder;
 
 namespace dom {
 
 class ClientInfoAndState;
+class KeepAliveToken;
 class ServiceWorkerCloneData;
 class ServiceWorkerInfo;
-class ServiceWorkerPrivate;
-class ServiceWorkerPrivateImpl;
 class ServiceWorkerRegistrationInfo;
 
 namespace ipc {
 class StructuredCloneData;
 }  // namespace ipc
 
 class LifeCycleEventCallback : public Runnable {
  public:
   LifeCycleEventCallback() : Runnable("dom::LifeCycleEventCallback") {}
 
   // Called on the worker thread.
   virtual void SetResult(bool aResult) = 0;
 };
 
-// Used to keep track of pending waitUntil as well as in-flight extendable
-// events. When the last token is released, we attempt to terminate the worker.
-class KeepAliveToken final : public nsISupports {
- public:
-  NS_DECL_ISUPPORTS
-
-  explicit KeepAliveToken(ServiceWorkerPrivate* aPrivate);
-
- private:
-  ~KeepAliveToken();
-
-  RefPtr<ServiceWorkerPrivate> mPrivate;
-};
-
 // ServiceWorkerPrivate is a wrapper for managing the on-demand aspect of
 // service workers. It handles all event dispatching to the worker and ensures
 // the worker thread is running when needed.
 //
 // Lifetime management: To spin up the worker thread we own a |WorkerPrivate|
 // object which can be cancelled if no events are received for a certain
 // amount of time. The worker is kept alive by holding a |KeepAliveToken|
 // reference.
@@ -84,72 +69,29 @@ class KeepAliveToken final : public nsIS
 // 3. The content process is shutting down.
 //
 // Adding an API function for a new event requires calling |SpawnWorkerIfNeeded|
 // with an appropriate reason before any runnable is dispatched to the worker.
 // If the event is extendable then the runnable should inherit
 // ExtendableEventWorkerRunnable.
 class ServiceWorkerPrivate final {
   friend class KeepAliveToken;
-  friend class ServiceWorkerPrivateImpl;
 
  public:
   NS_IMETHOD_(MozExternalRefCountType) AddRef();
   NS_IMETHOD_(MozExternalRefCountType) Release();
   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ServiceWorkerPrivate)
 
   typedef mozilla::FalseType HasThreadSafeRefCnt;
 
  protected:
   nsCycleCollectingAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
 
  public:
-  class Inner {
-   public:
-    NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
-
-    virtual nsresult SendMessageEvent(
-        RefPtr<ServiceWorkerCloneData>&& aData,
-        const ClientInfoAndState& aClientInfoAndState) = 0;
-
-    virtual nsresult CheckScriptEvaluation(
-        RefPtr<LifeCycleEventCallback> aScriptEvaluationCallback) = 0;
-
-    virtual nsresult SendLifeCycleEvent(
-        const nsAString& aEventName,
-        RefPtr<LifeCycleEventCallback> aCallback) = 0;
-
-    virtual nsresult SendPushEvent(
-        RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
-        const nsAString& aMessageId, const Maybe<nsTArray<uint8_t>>& aData) = 0;
-
-    virtual nsresult SendPushSubscriptionChangeEvent() = 0;
-
-    virtual nsresult SendNotificationEvent(
-        const nsAString& aEventName, const nsAString& aID,
-        const nsAString& aTitle, const nsAString& aDir, const nsAString& aLang,
-        const nsAString& aBody, const nsAString& aTag, const nsAString& aIcon,
-        const nsAString& aData, const nsAString& aBehavior,
-        const nsAString& aScope, uint32_t aDisableOpenClickDelay) = 0;
-
-    virtual nsresult SendFetchEvent(
-        RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
-        nsCOMPtr<nsIInterceptedChannel> aChannel, const nsAString& aClientId,
-        const nsAString& aResultingClientId, bool aIsReload) = 0;
-
-    virtual void TerminateWorker() = 0;
-
-    virtual void UpdateState(ServiceWorkerState aState) = 0;
-
-    virtual void NoteDeadOuter() = 0;
-
-    virtual bool WorkerIsDead() const = 0;
-  };
-
   explicit ServiceWorkerPrivate(ServiceWorkerInfo* aInfo);
 
   nsresult SendMessageEvent(RefPtr<ServiceWorkerCloneData>&& aData,
                             const ClientInfoAndState& aClientInfoAndState);
 
   // This is used to validate the worker script and continue the installation
   // process.
   nsresult CheckScriptEvaluation(LifeCycleEventCallback* aCallback);
@@ -208,18 +150,17 @@ class ServiceWorkerPrivate final {
   enum WakeUpReason {
     FetchEvent = 0,
     PushEvent,
     PushSubscriptionChangeEvent,
     MessageEvent,
     NotificationClickEvent,
     NotificationCloseEvent,
     LifeCycleEvent,
-    AttachEvent,
-    Unknown
+    AttachEvent
   };
 
   // Timer callbacks
   void NoteIdleWorkerCallback(nsITimer* aTimer);
 
   void TerminateWorkerCallback(nsITimer* aTimer);
 
   void RenewKeepAliveToken(WakeUpReason aWhy);
@@ -263,18 +204,16 @@ class ServiceWorkerPrivate final {
   // |StoreISupports| and |RemoveISupports|. Note that the array is also
   // cleared whenever the worker is terminated.
   nsTArray<nsCOMPtr<nsISupports>> mSupportsArray;
 
   // Array of function event worker runnables that are pending due to
   // the worker activating.  Main thread only.
   nsTArray<RefPtr<WorkerRunnable>> mPendingFunctionalEvents;
 
-  RefPtr<Inner> mInner;
-
   // Used by the owning `ServiceWorkerRegistrationInfo` when it wants to call
   // `Clear` after being unregistered and isn't controlling any clients but this
   // worker (i.e. the registration's active worker) isn't idle yet. Note that
   // such an event should happen at most once in a
   // `ServiceWorkerRegistrationInfo`s lifetime, so this promise should also only
   // be obtained at most once.
   MozPromiseHolder<GenericPromise> mIdlePromiseHolder;
 
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerPrivateImpl.cpp
+++ /dev/null
@@ -1,1110 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "ServiceWorkerPrivateImpl.h"
-
-#include <utility>
-
-#include "MainThreadUtils.h"
-#include "js/ErrorReport.h"
-#include "nsContentUtils.h"
-#include "nsDebug.h"
-#include "nsError.h"
-#include "nsICacheInfoChannel.h"
-#include "nsIChannel.h"
-#include "nsIHttpChannel.h"
-#include "nsIHttpChannelInternal.h"
-#include "nsIHttpHeaderVisitor.h"
-#include "nsIInputStream.h"
-#include "nsILoadInfo.h"
-#include "nsINetworkInterceptController.h"
-#include "nsIObserverService.h"
-#include "nsIPermissionManager.h"
-#include "nsIURI.h"
-#include "nsIUploadChannel2.h"
-#include "nsPermissionManager.h"
-#include "nsThreadUtils.h"
-
-#include "ServiceWorkerManager.h"
-#include "ServiceWorkerRegistrationInfo.h"
-#include "mozilla/Assertions.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Maybe.h"
-#include "mozilla/ScopeExit.h"
-#include "mozilla/Services.h"
-#include "mozilla/StaticPrefs_dom.h"
-#include "mozilla/SystemGroup.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/ClientIPCTypes.h"
-#include "mozilla/dom/DOMTypes.h"
-#include "mozilla/dom/FetchEventOpChild.h"
-#include "mozilla/dom/InternalHeaders.h"
-#include "mozilla/dom/InternalRequest.h"
-#include "mozilla/dom/ReferrerInfo.h"
-#include "mozilla/dom/RemoteWorkerControllerChild.h"
-#include "mozilla/dom/ServiceWorkerBinding.h"
-#include "mozilla/ipc/BackgroundChild.h"
-#include "mozilla/ipc/IPCStreamUtils.h"
-
-namespace mozilla {
-
-using namespace ipc;
-
-namespace dom {
-
-namespace {
-
-class HeaderFiller final : public nsIHttpHeaderVisitor {
- public:
-  NS_DECL_ISUPPORTS
-
-  explicit HeaderFiller(HeadersGuardEnum aGuard)
-      : mInternalHeaders(new InternalHeaders(aGuard)) {
-    MOZ_ASSERT(mInternalHeaders);
-  }
-
-  NS_IMETHOD
-  VisitHeader(const nsACString& aHeader, const nsACString& aValue) override {
-    ErrorResult result;
-    mInternalHeaders->Append(aHeader, aValue, result);
-
-    if (NS_WARN_IF(result.Failed())) {
-      return result.StealNSResult();
-    }
-
-    return NS_OK;
-  }
-
-  RefPtr<InternalHeaders> Extract() {
-    return RefPtr<InternalHeaders>(std::move(mInternalHeaders));
-  }
-
- private:
-  ~HeaderFiller() = default;
-
-  RefPtr<InternalHeaders> mInternalHeaders;
-};
-
-NS_IMPL_ISUPPORTS(HeaderFiller, nsIHttpHeaderVisitor)
-
-nsresult GetIPCInternalRequest(nsIInterceptedChannel* aChannel,
-                               IPCInternalRequest* aOutRequest,
-                               UniquePtr<AutoIPCStream>& aAutoStream) {
-  AssertIsOnMainThread();
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = aChannel->GetSecureUpgradedChannelURI(getter_AddRefs(uri));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIURI> uriNoFragment;
-  rv = NS_GetURIWithoutRef(uri, getter_AddRefs(uriNoFragment));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIChannel> underlyingChannel;
-  rv = aChannel->GetChannel(getter_AddRefs(underlyingChannel));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(underlyingChannel);
-  MOZ_ASSERT(httpChannel, "How come we don't have an HTTP channel?");
-
-  nsCOMPtr<nsIHttpChannelInternal> internalChannel =
-      do_QueryInterface(httpChannel);
-  NS_ENSURE_TRUE(internalChannel, NS_ERROR_NOT_AVAILABLE);
-
-  nsCOMPtr<nsICacheInfoChannel> cacheInfoChannel =
-      do_QueryInterface(underlyingChannel);
-
-  nsAutoCString spec;
-  rv = uriNoFragment->GetSpec(spec);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoCString fragment;
-  rv = uri->GetRef(fragment);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoCString method;
-  rv = httpChannel->GetRequestMethod(method);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // This is safe due to static_asserts in ServiceWorkerManager.cpp
-  uint32_t cacheModeInt;
-  rv = internalChannel->GetFetchCacheMode(&cacheModeInt);
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-  RequestCache cacheMode = static_cast<RequestCache>(cacheModeInt);
-
-  RequestMode requestMode =
-      InternalRequest::MapChannelToRequestMode(underlyingChannel);
-
-  // This is safe due to static_asserts in ServiceWorkerManager.cpp
-  uint32_t redirectMode;
-  rv = internalChannel->GetRedirectMode(&redirectMode);
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-  RequestRedirect requestRedirect = static_cast<RequestRedirect>(redirectMode);
-
-  RequestCredentials requestCredentials =
-      InternalRequest::MapChannelToRequestCredentials(underlyingChannel);
-
-  nsCString referrer = EmptyCString();
-  uint32_t referrerPolicyInt = 0;
-
-  nsCOMPtr<nsIReferrerInfo> referrerInfo = httpChannel->GetReferrerInfo();
-  if (referrerInfo) {
-    referrerPolicyInt = referrerInfo->GetReferrerPolicy();
-    nsCOMPtr<nsIURI> computedReferrer = referrerInfo->GetComputedReferrer();
-    if (computedReferrer) {
-      rv = computedReferrer->GetSpec(referrer);
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-  }
-
-  ReferrerPolicy referrerPolicy;
-  switch (referrerPolicyInt) {
-    case nsIHttpChannel::REFERRER_POLICY_UNSET:
-      referrerPolicy = ReferrerPolicy::_empty;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_NO_REFERRER:
-      referrerPolicy = ReferrerPolicy::No_referrer;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_ORIGIN:
-      referrerPolicy = ReferrerPolicy::Origin;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE:
-      referrerPolicy = ReferrerPolicy::No_referrer_when_downgrade;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_ORIGIN_WHEN_XORIGIN:
-      referrerPolicy = ReferrerPolicy::Origin_when_cross_origin;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_UNSAFE_URL:
-      referrerPolicy = ReferrerPolicy::Unsafe_url;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_SAME_ORIGIN:
-      referrerPolicy = ReferrerPolicy::Same_origin;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_STRICT_ORIGIN_WHEN_XORIGIN:
-      referrerPolicy = ReferrerPolicy::Strict_origin_when_cross_origin;
-      break;
-    case nsIHttpChannel::REFERRER_POLICY_STRICT_ORIGIN:
-      referrerPolicy = ReferrerPolicy::Strict_origin;
-      break;
-    default:
-      MOZ_ASSERT_UNREACHABLE("Invalid Referrer Policy enum value?");
-      break;
-  }
-
-  uint32_t loadFlags;
-  rv = underlyingChannel->GetLoadFlags(&loadFlags);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsILoadInfo> loadInfo;
-  rv = underlyingChannel->GetLoadInfo(getter_AddRefs(loadInfo));
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_STATE(loadInfo);
-
-  nsContentPolicyType contentPolicyType = loadInfo->InternalContentPolicyType();
-
-  nsAutoString integrity;
-  rv = internalChannel->GetIntegrityMetadata(integrity);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  RefPtr<HeaderFiller> headerFiller =
-      MakeRefPtr<HeaderFiller>(HeadersGuardEnum::Request);
-  rv = httpChannel->VisitNonDefaultRequestHeaders(headerFiller);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  RefPtr<InternalHeaders> internalHeaders = headerFiller->Extract();
-
-  ErrorResult result;
-  internalHeaders->SetGuard(HeadersGuardEnum::Immutable, result);
-  if (NS_WARN_IF(result.Failed())) {
-    return result.StealNSResult();
-  }
-
-  nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(httpChannel);
-  nsCOMPtr<nsIInputStream> uploadStream;
-  int64_t uploadStreamContentLength = -1;
-  if (uploadChannel) {
-    rv = uploadChannel->CloneUploadStream(&uploadStreamContentLength,
-                                          getter_AddRefs(uploadStream));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  RefPtr<InternalRequest> internalRequest = new InternalRequest(
-      spec, fragment, method, internalHeaders.forget(), cacheMode, requestMode,
-      requestRedirect, requestCredentials, NS_ConvertUTF8toUTF16(referrer),
-      referrerPolicy, contentPolicyType, integrity);
-  internalRequest->SetBody(uploadStream, uploadStreamContentLength);
-  internalRequest->SetCreatedByFetchEvent();
-
-  nsAutoCString alternativeDataType;
-  if (cacheInfoChannel &&
-      !cacheInfoChannel->PreferredAlternativeDataTypes().IsEmpty()) {
-    // TODO: the internal request probably needs all the preferred types.
-    alternativeDataType.Assign(
-        cacheInfoChannel->PreferredAlternativeDataTypes()[0].type());
-    internalRequest->SetPreferredAlternativeDataType(alternativeDataType);
-  }
-
-  PBackgroundChild* bgChild = BackgroundChild::GetForCurrentThread();
-
-  if (NS_WARN_IF(!bgChild)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  internalRequest->ToIPC(aOutRequest, bgChild, aAutoStream);
-
-  return NS_OK;
-}
-
-}  // anonymous namespace
-
-ServiceWorkerPrivateImpl::RAIIActorPtrHolder::RAIIActorPtrHolder(
-    already_AddRefed<RemoteWorkerControllerChild> aActor)
-    : mActor(aActor) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mActor);
-  MOZ_ASSERT(mActor->Manager());
-}
-
-ServiceWorkerPrivateImpl::RAIIActorPtrHolder::~RAIIActorPtrHolder() {
-  AssertIsOnMainThread();
-
-  mDestructorPromiseHolder.ResolveIfExists(true, __func__);
-
-  mActor->MaybeSendDelete();
-}
-
-RemoteWorkerControllerChild* ServiceWorkerPrivateImpl::RAIIActorPtrHolder::
-operator->() const {
-  AssertIsOnMainThread();
-
-  return get();
-}
-
-RemoteWorkerControllerChild* ServiceWorkerPrivateImpl::RAIIActorPtrHolder::get()
-    const {
-  AssertIsOnMainThread();
-
-  return mActor.get();
-}
-
-RefPtr<GenericPromise>
-ServiceWorkerPrivateImpl::RAIIActorPtrHolder::OnDestructor() {
-  AssertIsOnMainThread();
-
-  return mDestructorPromiseHolder.Ensure(__func__);
-}
-
-ServiceWorkerPrivateImpl::ServiceWorkerPrivateImpl(
-    RefPtr<ServiceWorkerPrivate> aOuter)
-    : mOuter(std::move(aOuter)) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(WorkerIsDead());
-}
-
-nsresult ServiceWorkerPrivateImpl::Initialize() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mOuter->mInfo);
-
-  nsCOMPtr<nsIPrincipal> principal = mOuter->mInfo->Principal();
-
-  nsCOMPtr<nsIURI> uri;
-  nsresult rv = principal->GetURI(getter_AddRefs(uri));
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  if (NS_WARN_IF(!uri)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  URIParams baseScriptURL;
-  SerializeURI(uri, baseScriptURL);
-
-  PrincipalInfo principalInfo;
-  rv = PrincipalToPrincipalInfo(principal, &principalInfo);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-
-  if (NS_WARN_IF(!swm)) {
-    return NS_ERROR_DOM_ABORT_ERR;
-  }
-
-  RefPtr<ServiceWorkerRegistrationInfo> regInfo =
-      swm->GetRegistration(principal, mOuter->mInfo->Scope());
-
-  if (NS_WARN_IF(!regInfo)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  nsCOMPtr<nsICookieSettings> cookieSettings =
-      mozilla::net::CookieSettings::Create();
-  MOZ_ASSERT(cookieSettings);
-
-  StorageAccess storageAccess =
-      StorageAllowedForServiceWorker(principal, cookieSettings);
-
-  ServiceWorkerData serviceWorkerData;
-  serviceWorkerData.cacheName() = mOuter->mInfo->CacheName();
-  serviceWorkerData.loadFlags() =
-      static_cast<uint32_t>(mOuter->mInfo->GetImportsLoadFlags() |
-                            nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
-
-  mRemoteWorkerData.originalScriptURL() =
-      NS_ConvertUTF8toUTF16(mOuter->mInfo->ScriptSpec());
-  mRemoteWorkerData.baseScriptURL() = baseScriptURL;
-  mRemoteWorkerData.resolvedScriptURL() = baseScriptURL;
-  mRemoteWorkerData.name() = VoidString();
-
-  mRemoteWorkerData.loadingPrincipalInfo() = principalInfo;
-  mRemoteWorkerData.principalInfo() = principalInfo;
-  // storagePrincipalInfo for ServiceWorkers is equal to principalInfo because,
-  // at the moment, ServiceWorkers are not exposed in partitioned contexts.
-  mRemoteWorkerData.storagePrincipalInfo() = principalInfo;
-
-  rv = uri->GetHost(mRemoteWorkerData.domain());
-  NS_ENSURE_SUCCESS(rv, rv);
-  mRemoteWorkerData.isSecureContext() = true;
-  mRemoteWorkerData.referrerInfo() = MakeAndAddRef<ReferrerInfo>();
-  mRemoteWorkerData.storageAccess() = storageAccess;
-  mRemoteWorkerData.serviceWorkerData() = std::move(serviceWorkerData);
-
-  // This fills in the rest of mRemoteWorkerData.serviceWorkerData().
-  rv = RefreshRemoteWorkerData(regInfo);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-RefPtr<GenericPromise> ServiceWorkerPrivateImpl::SetSkipWaitingFlag() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mOuter->mInfo);
-
-  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-
-  if (!swm) {
-    return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
-  }
-
-  RefPtr<ServiceWorkerRegistrationInfo> regInfo =
-      swm->GetRegistration(mOuter->mInfo->Principal(), mOuter->mInfo->Scope());
-
-  if (!regInfo) {
-    return GenericPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
-  }
-
-  mOuter->mInfo->SetSkipWaitingFlag();
-
-  RefPtr<GenericPromise::Private> promise =
-      new GenericPromise::Private(__func__);
-
-  regInfo->TryToActivateAsync([promise] { promise->Resolve(true, __func__); });
-
-  return promise;
-}
-
-nsresult ServiceWorkerPrivateImpl::RefreshRemoteWorkerData(
-    const RefPtr<ServiceWorkerRegistrationInfo>& aRegistration) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mOuter->mInfo);
-
-  nsTArray<KeyAndPermissions> permissions;
-  nsCOMPtr<nsIPermissionManager> permManager = services::GetPermissionManager();
-  nsTArray<nsCString> keys =
-      nsPermissionManager::GetAllKeysForPrincipal(mOuter->mInfo->Principal());
-  MOZ_ASSERT(!keys.IsEmpty());
-
-  for (auto& key : keys) {
-    nsTArray<IPC::Permission> perms;
-    nsresult rv = permManager->GetPermissionsWithKey(key, perms);
-
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    KeyAndPermissions kp;
-    kp.key() = nsCString(key);
-    kp.permissions() = std::move(perms);
-
-    permissions.AppendElement(std::move(kp));
-  }
-
-  MOZ_ASSERT(!permissions.IsEmpty());
-
-  ServiceWorkerData& serviceWorkerData =
-      mRemoteWorkerData.serviceWorkerData().get_ServiceWorkerData();
-  serviceWorkerData.permissionsByKey() = std::move(permissions);
-  serviceWorkerData.descriptor() = mOuter->mInfo->Descriptor().ToIPC();
-  serviceWorkerData.registrationDescriptor() =
-      aRegistration->Descriptor().ToIPC();
-
-  return NS_OK;
-}
-
-nsresult ServiceWorkerPrivateImpl::SpawnWorkerIfNeeded() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mOuter->mInfo);
-
-  if (mControllerChild) {
-    return NS_OK;
-  }
-
-  PBackgroundChild* bgChild = BackgroundChild::GetForCurrentThread();
-
-  if (NS_WARN_IF(!bgChild)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-
-  if (NS_WARN_IF(!swm)) {
-    return NS_ERROR_DOM_ABORT_ERR;
-  }
-
-  RefPtr<ServiceWorkerRegistrationInfo> regInfo =
-      swm->GetRegistration(mOuter->mInfo->Principal(), mOuter->mInfo->Scope());
-
-  if (NS_WARN_IF(!regInfo)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  nsresult rv = RefreshRemoteWorkerData(regInfo);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  RefPtr<RemoteWorkerControllerChild> controllerChild =
-      new RemoteWorkerControllerChild(this);
-
-  if (NS_WARN_IF(!bgChild->SendPRemoteWorkerControllerConstructor(
-          controllerChild, mRemoteWorkerData))) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  /**
-   * Manutally `AddRef()` because `DeallocPRemoteWorkerControllerChild()`
-   * calls `Release()` and the `AllocPRemoteWorkerControllerChild()` function
-   * is not called.
-   */
-  // NOLINTNEXTLINE(readability-redundant-smartptr-get)
-  controllerChild.get()->AddRef();
-
-  mControllerChild = new RAIIActorPtrHolder(controllerChild.forget());
-
-  return NS_OK;
-}
-
-ServiceWorkerPrivateImpl::~ServiceWorkerPrivateImpl() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(!mOuter);
-  MOZ_ASSERT(WorkerIsDead());
-}
-
-nsresult ServiceWorkerPrivateImpl::SendMessageEvent(
-    RefPtr<ServiceWorkerCloneData>&& aData,
-    const ClientInfoAndState& aClientInfoAndState) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(aData);
-
-  auto scopeExit = MakeScopeExit([&] { Shutdown(); });
-
-  PBackgroundChild* bgChild = BackgroundChild::GetForCurrentThread();
-
-  if (NS_WARN_IF(!bgChild)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  ServiceWorkerMessageEventOpArgs args;
-  args.clientInfoAndState() = aClientInfoAndState;
-  if (!aData->BuildClonedMessageDataForBackgroundChild(bgChild,
-                                                       args.clonedData())) {
-    return NS_ERROR_DOM_DATA_CLONE_ERR;
-  }
-
-  scopeExit.release();
-
-  return ExecServiceWorkerOp(
-      std::move(args), [](ServiceWorkerOpResult&& aResult) {
-        MOZ_ASSERT(aResult.type() == ServiceWorkerOpResult::Tnsresult);
-      });
-}
-
-nsresult ServiceWorkerPrivateImpl::CheckScriptEvaluation(
-    RefPtr<LifeCycleEventCallback> aCallback) {
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(aCallback);
-
-  RefPtr<ServiceWorkerPrivateImpl> self = this;
-
-  /**
-   * We need to capture the actor associated with the current Service Worker so
-   * we can terminate it if script evaluation failed.
-   */
-  nsresult rv = SpawnWorkerIfNeeded();
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aCallback->SetResult(false);
-    aCallback->Run();
-
-    return rv;
-  }
-
-  MOZ_ASSERT(mControllerChild);
-
-  RefPtr<RAIIActorPtrHolder> holder = mControllerChild;
-
-  return ExecServiceWorkerOp(
-      ServiceWorkerCheckScriptEvaluationOpArgs(),
-      [self = std::move(self), holder = std::move(holder),
-       callback = aCallback](ServiceWorkerOpResult&& aResult) mutable {
-        if (aResult.type() == ServiceWorkerOpResult::
-                                  TServiceWorkerCheckScriptEvaluationOpResult) {
-          auto& result =
-              aResult.get_ServiceWorkerCheckScriptEvaluationOpResult();
-
-          if (result.workerScriptExecutedSuccessfully()) {
-            if (self->mOuter) {
-              self->mOuter->SetHandlesFetch(result.fetchHandlerWasAdded());
-            }
-
-            Unused << NS_WARN_IF(!self->mOuter);
-
-            callback->SetResult(result.workerScriptExecutedSuccessfully());
-            callback->Run();
-
-            return;
-          }
-        }
-
-        /**
-         * If script evaluation failed, first terminate the Service Worker
-         * before invoking the callback.
-         */
-        MOZ_ASSERT_IF(aResult.type() == ServiceWorkerOpResult::Tnsresult,
-                      NS_FAILED(aResult.get_nsresult()));
-
-        // If a termination operation was already issued using `holder`...
-        if (self->mControllerChild != holder) {
-          holder->OnDestructor()->Then(
-              GetCurrentThreadSerialEventTarget(), __func__,
-              [callback = std::move(callback)](
-                  const GenericPromise::ResolveOrRejectValue&) {
-                callback->SetResult(false);
-                callback->Run();
-              });
-
-          return;
-        }
-
-        RefPtr<GenericNonExclusivePromise> promise = self->ShutdownInternal();
-
-        RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-        MOZ_ASSERT(swm);
-
-        swm->BlockShutdownOn(promise);
-
-        promise->Then(
-            GetCurrentThreadSerialEventTarget(), __func__,
-            [callback = std::move(callback)](
-                const GenericNonExclusivePromise::ResolveOrRejectValue&) {
-              callback->SetResult(false);
-              callback->Run();
-            });
-      },
-      [callback = aCallback] {
-        callback->SetResult(false);
-        callback->Run();
-      });
-}
-
-nsresult ServiceWorkerPrivateImpl::SendLifeCycleEvent(
-    const nsAString& aEventName, RefPtr<LifeCycleEventCallback> aCallback) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(aCallback);
-
-  return ExecServiceWorkerOp(
-      ServiceWorkerLifeCycleEventOpArgs(nsString(aEventName)),
-      [callback = aCallback](ServiceWorkerOpResult&& aResult) {
-        MOZ_ASSERT(aResult.type() == ServiceWorkerOpResult::Tnsresult);
-
-        callback->SetResult(NS_SUCCEEDED(aResult.get_nsresult()));
-        callback->Run();
-      },
-      [callback = aCallback] {
-        callback->SetResult(false);
-        callback->Run();
-      });
-}
-
-nsresult ServiceWorkerPrivateImpl::SendPushEvent(
-    RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
-    const nsAString& aMessageId, const Maybe<nsTArray<uint8_t>>& aData) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(aRegistration);
-
-  ServiceWorkerPushEventOpArgs args;
-  args.messageId() = nsString(aMessageId);
-
-  if (aData) {
-    args.data() = aData.ref();
-  } else {
-    args.data() = void_t();
-  }
-
-  if (mOuter->mInfo->State() == ServiceWorkerState::Activating) {
-    UniquePtr<PendingFunctionalEvent> pendingEvent =
-        MakeUnique<PendingPushEvent>(this, std::move(aRegistration),
-                                     std::move(args));
-
-    mPendingFunctionalEvents.AppendElement(std::move(pendingEvent));
-
-    return NS_OK;
-  }
-
-  MOZ_ASSERT(mOuter->mInfo->State() == ServiceWorkerState::Activated);
-
-  return SendPushEventInternal(std::move(aRegistration), std::move(args));
-}
-
-nsresult ServiceWorkerPrivateImpl::SendPushEventInternal(
-    RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-    ServiceWorkerPushEventOpArgs&& aArgs) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(aRegistration);
-
-  return ExecServiceWorkerOp(
-      std::move(aArgs),
-      [registration = aRegistration](ServiceWorkerOpResult&& aResult) {
-        MOZ_ASSERT(aResult.type() == ServiceWorkerOpResult::Tnsresult);
-
-        registration->MaybeScheduleTimeCheckAndUpdate();
-      },
-      [registration = aRegistration]() {
-        registration->MaybeScheduleTimeCheckAndUpdate();
-      });
-}
-
-nsresult ServiceWorkerPrivateImpl::SendPushSubscriptionChangeEvent() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-
-  return ExecServiceWorkerOp(
-      ServiceWorkerPushSubscriptionChangeEventOpArgs(),
-      [](ServiceWorkerOpResult&& aResult) {
-        MOZ_ASSERT(aResult.type() == ServiceWorkerOpResult::Tnsresult);
-      });
-}
-
-nsresult ServiceWorkerPrivateImpl::SendNotificationEvent(
-    const nsAString& aEventName, const nsAString& aID, const nsAString& aTitle,
-    const nsAString& aDir, const nsAString& aLang, const nsAString& aBody,
-    const nsAString& aTag, const nsAString& aIcon, const nsAString& aData,
-    const nsAString& aBehavior, const nsAString& aScope,
-    uint32_t aDisableOpenClickDelay) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-
-  ServiceWorkerNotificationEventOpArgs args;
-  args.eventName() = nsString(aEventName);
-  args.id() = nsString(aID);
-  args.title() = nsString(aTitle);
-  args.dir() = nsString(aDir);
-  args.lang() = nsString(aLang);
-  args.body() = nsString(aBody);
-  args.tag() = nsString(aTag);
-  args.icon() = nsString(aIcon);
-  args.data() = nsString(aData);
-  args.behavior() = nsString(aBehavior);
-  args.scope() = nsString(aScope);
-  args.disableOpenClickDelay() = aDisableOpenClickDelay;
-
-  return ExecServiceWorkerOp(
-      std::move(args), [](ServiceWorkerOpResult&& aResult) {
-        MOZ_ASSERT(aResult.type() == ServiceWorkerOpResult::Tnsresult);
-      });
-}
-
-ServiceWorkerPrivateImpl::PendingFunctionalEvent::PendingFunctionalEvent(
-    ServiceWorkerPrivateImpl* aOwner,
-    RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration)
-    : mOwner(aOwner), mRegistration(std::move(aRegistration)) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOwner);
-  MOZ_ASSERT(mOwner->mOuter);
-  MOZ_ASSERT(mOwner->mOuter->mInfo);
-  MOZ_ASSERT(mOwner->mOuter->mInfo->State() == ServiceWorkerState::Activating);
-  MOZ_ASSERT(mRegistration);
-}
-
-ServiceWorkerPrivateImpl::PendingFunctionalEvent::~PendingFunctionalEvent() {
-  AssertIsOnMainThread();
-}
-
-ServiceWorkerPrivateImpl::PendingPushEvent::PendingPushEvent(
-    ServiceWorkerPrivateImpl* aOwner,
-    RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-    ServiceWorkerPushEventOpArgs&& aArgs)
-    : PendingFunctionalEvent(aOwner, std::move(aRegistration)),
-      mArgs(std::move(aArgs)) {
-  AssertIsOnMainThread();
-}
-
-nsresult ServiceWorkerPrivateImpl::PendingPushEvent::Send() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOwner->mOuter);
-  MOZ_ASSERT(mOwner->mOuter->mInfo);
-
-  return mOwner->SendPushEventInternal(std::move(mRegistration),
-                                       std::move(mArgs));
-}
-
-ServiceWorkerPrivateImpl::PendingFetchEvent::PendingFetchEvent(
-    ServiceWorkerPrivateImpl* aOwner,
-    RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-    ServiceWorkerFetchEventOpArgs&& aArgs,
-    nsCOMPtr<nsIInterceptedChannel>&& aChannel,
-    UniquePtr<AutoIPCStream>&& aAutoStream)
-    : PendingFunctionalEvent(aOwner, std::move(aRegistration)),
-      mArgs(std::move(aArgs)),
-      mChannel(std::move(aChannel)),
-      mAutoStream(std::move(aAutoStream)) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mChannel);
-  MOZ_ASSERT(mAutoStream);
-}
-
-nsresult ServiceWorkerPrivateImpl::PendingFetchEvent::Send() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOwner->mOuter);
-  MOZ_ASSERT(mOwner->mOuter->mInfo);
-
-  return mOwner->SendFetchEventInternal(std::move(mRegistration),
-                                        std::move(mArgs), std::move(mChannel),
-                                        std::move(mAutoStream));
-}
-
-ServiceWorkerPrivateImpl::PendingFetchEvent::~PendingFetchEvent() {
-  AssertIsOnMainThread();
-
-  if (NS_WARN_IF(mChannel)) {
-    mChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
-  }
-}
-
-nsresult ServiceWorkerPrivateImpl::SendFetchEvent(
-    RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
-    nsCOMPtr<nsIInterceptedChannel> aChannel, const nsAString& aClientId,
-    const nsAString& aResultingClientId, bool aIsReload) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(aRegistration);
-  MOZ_ASSERT(aChannel);
-
-  auto scopeExit = MakeScopeExit([&] {
-    aChannel->CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
-    Shutdown();
-  });
-
-  nsCOMPtr<nsIChannel> channel;
-  nsresult rv = aChannel->GetChannel(getter_AddRefs(channel));
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  IPCInternalRequest internalRequest;
-  UniquePtr<AutoIPCStream> autoStream = MakeUnique<AutoIPCStream>();
-  rv = GetIPCInternalRequest(aChannel, &internalRequest, autoStream);
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  scopeExit.release();
-
-  MOZ_ASSERT(mOuter->mInfo);
-
-  ServiceWorkerFetchEventOpArgs args(
-      mOuter->mInfo->ScriptSpec(), internalRequest, nsString(aClientId),
-      nsString(aResultingClientId), aIsReload,
-      nsContentUtils::IsNonSubresourceRequest(channel));
-
-  if (mOuter->mInfo->State() == ServiceWorkerState::Activating) {
-    UniquePtr<PendingFunctionalEvent> pendingEvent =
-        MakeUnique<PendingFetchEvent>(this, std::move(aRegistration),
-                                      std::move(args), std::move(aChannel),
-                                      std::move(autoStream));
-
-    mPendingFunctionalEvents.AppendElement(std::move(pendingEvent));
-
-    return NS_OK;
-  }
-
-  MOZ_ASSERT(mOuter->mInfo->State() == ServiceWorkerState::Activated);
-
-  return SendFetchEventInternal(std::move(aRegistration), std::move(args),
-                                std::move(aChannel), std::move(autoStream));
-}
-
-nsresult ServiceWorkerPrivateImpl::SendFetchEventInternal(
-    RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-    ServiceWorkerFetchEventOpArgs&& aArgs,
-    nsCOMPtr<nsIInterceptedChannel>&& aChannel,
-    UniquePtr<AutoIPCStream>&& aAutoStream) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-
-  auto scopeExit = MakeScopeExit([&] { Shutdown(); });
-
-  if (NS_WARN_IF(!mOuter->mInfo)) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
-  }
-
-  nsresult rv = SpawnWorkerIfNeeded();
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  scopeExit.release();
-
-  MOZ_ASSERT(mControllerChild);
-
-  RefPtr<RAIIActorPtrHolder> holder = mControllerChild;
-
-  FetchEventOpChild::Create(mControllerChild->get(), std::move(aArgs),
-                            std::move(aChannel), std::move(aRegistration),
-                            mOuter->CreateEventKeepAliveToken())
-      ->Then(GetCurrentThreadSerialEventTarget(), __func__,
-             [holder = std::move(holder)](
-                 const GenericPromise::ResolveOrRejectValue& aResult) {
-               Unused << NS_WARN_IF(aResult.IsReject());
-             });
-
-  aAutoStream->TakeOptionalValue();
-
-  return NS_OK;
-}
-
-void ServiceWorkerPrivateImpl::TerminateWorker() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-
-  mOuter->mIdleWorkerTimer->Cancel();
-  mOuter->mIdleKeepAliveToken = nullptr;
-
-  Shutdown();
-}
-
-void ServiceWorkerPrivateImpl::Shutdown() {
-  AssertIsOnMainThread();
-
-  if (!WorkerIsDead()) {
-    RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-
-    MOZ_ASSERT(swm,
-               "All Service Workers should start shutting down before the "
-               "ServiceWorkerManager does!");
-
-    RefPtr<GenericNonExclusivePromise> promise = ShutdownInternal();
-    swm->BlockShutdownOn(promise);
-  }
-
-  MOZ_ASSERT(WorkerIsDead());
-}
-
-RefPtr<GenericNonExclusivePromise>
-ServiceWorkerPrivateImpl::ShutdownInternal() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mControllerChild);
-
-  mPendingFunctionalEvents.Clear();
-
-  mControllerChild->get()->RevokeObserver(this);
-
-  if (StaticPrefs::dom_serviceWorkers_testing_enabled()) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    if (os) {
-      os->NotifyObservers(nullptr, "service-worker-shutdown", nullptr);
-    }
-  }
-
-  RefPtr<GenericNonExclusivePromise::Private> promise =
-      new GenericNonExclusivePromise::Private(__func__);
-
-  Unused << ExecServiceWorkerOp(
-      ServiceWorkerTerminateWorkerOpArgs(),
-      [promise](ServiceWorkerOpResult&& aResult) {
-        MOZ_ASSERT(aResult.type() == ServiceWorkerOpResult::Tnsresult);
-        promise->Resolve(true, __func__);
-      },
-      [promise]() { promise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__); });
-
-  /**
-   * After dispatching a termination operation, no new operations should
-   * be routed through this actor anymore.
-   */
-  mControllerChild = nullptr;
-
-  return promise;
-}
-
-void ServiceWorkerPrivateImpl::UpdateState(ServiceWorkerState aState) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-
-  if (WorkerIsDead()) {
-    return;
-  }
-
-  nsresult rv = ExecServiceWorkerOp(
-      ServiceWorkerUpdateStateOpArgs(aState),
-      [](ServiceWorkerOpResult&& aResult) {
-        MOZ_ASSERT(aResult.type() == ServiceWorkerOpResult::Tnsresult);
-      });
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    Shutdown();
-    return;
-  }
-
-  if (aState != ServiceWorkerState::Activated) {
-    return;
-  }
-
-  for (auto& event : mPendingFunctionalEvents) {
-    Unused << NS_WARN_IF(NS_FAILED(event->Send()));
-  }
-
-  mPendingFunctionalEvents.Clear();
-}
-
-void ServiceWorkerPrivateImpl::NoteDeadOuter() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-
-  Shutdown();
-  mOuter = nullptr;
-}
-
-void ServiceWorkerPrivateImpl::CreationFailed() {
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mControllerChild);
-
-  Shutdown();
-}
-
-void ServiceWorkerPrivateImpl::CreationSucceeded() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mControllerChild);
-
-  mOuter->RenewKeepAliveToken(ServiceWorkerPrivate::WakeUpReason::Unknown);
-}
-
-void ServiceWorkerPrivateImpl::ErrorReceived(const ErrorValue& aError) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mOuter->mInfo);
-  MOZ_ASSERT(mControllerChild);
-
-  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-  MOZ_ASSERT(swm);
-
-  ServiceWorkerInfo* info = mOuter->mInfo;
-
-  swm->HandleError(nullptr, info->Principal(), info->Scope(),
-                   NS_ConvertUTF8toUTF16(info->ScriptSpec()), EmptyString(),
-                   EmptyString(), EmptyString(), 0, 0, JSREPORT_ERROR,
-                   JSEXN_ERR);
-}
-
-void ServiceWorkerPrivateImpl::Terminated() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(mControllerChild);
-
-  Shutdown();
-}
-
-bool ServiceWorkerPrivateImpl::WorkerIsDead() const {
-  AssertIsOnMainThread();
-
-  return !mControllerChild;
-}
-
-nsresult ServiceWorkerPrivateImpl::ExecServiceWorkerOp(
-    ServiceWorkerOpArgs&& aArgs,
-    std::function<void(ServiceWorkerOpResult&&)>&& aSuccessCallback,
-    std::function<void()>&& aFailureCallback) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mOuter);
-  MOZ_ASSERT(
-      aArgs.type() != ServiceWorkerOpArgs::TServiceWorkerFetchEventOpArgs,
-      "FetchEvent operations should be sent through FetchEventOp(Proxy) "
-      "actors!");
-  MOZ_ASSERT(aSuccessCallback);
-
-  nsresult rv = SpawnWorkerIfNeeded();
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    aFailureCallback();
-    return rv;
-  }
-
-  MOZ_ASSERT(mControllerChild);
-
-  RefPtr<ServiceWorkerPrivateImpl> self = this;
-  RefPtr<RAIIActorPtrHolder> holder = mControllerChild;
-  RefPtr<KeepAliveToken> token =
-      aArgs.type() == ServiceWorkerOpArgs::TServiceWorkerTerminateWorkerOpArgs
-          ? nullptr
-          : mOuter->CreateEventKeepAliveToken();
-
-  /**
-   * NOTE: moving `aArgs` won't do anything until IPDL `SendMethod()` methods
-   * can accept rvalue references rather than just const references.
-   */
-  mControllerChild->get()->SendExecServiceWorkerOp(aArgs)->Then(
-      GetCurrentThreadSerialEventTarget(), __func__,
-      [self = std::move(self), holder = std::move(holder),
-       token = std::move(token), onSuccess = std::move(aSuccessCallback),
-       onFailure = std::move(aFailureCallback)](
-          PRemoteWorkerControllerChild::ExecServiceWorkerOpPromise::
-              ResolveOrRejectValue&& aResult) {
-        if (NS_WARN_IF(aResult.IsReject())) {
-          onFailure();
-          return;
-        }
-
-        onSuccess(std::move(aResult.ResolveValue()));
-      });
-
-  return NS_OK;
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerPrivateImpl.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_serviceworkerprivateimpl_h__
-#define mozilla_dom_serviceworkerprivateimpl_h__
-
-#include <functional>
-
-#include "nsCOMPtr.h"
-#include "nsISupportsImpl.h"
-#include "nsTArray.h"
-
-#include "ServiceWorkerPrivate.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/MozPromise.h"
-#include "mozilla/RefPtr.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/dom/RemoteWorkerController.h"
-#include "mozilla/dom/RemoteWorkerTypes.h"
-#include "mozilla/dom/ServiceWorkerOpArgs.h"
-
-class nsIInterceptedChannel;
-
-namespace mozilla {
-
-template <typename T>
-class Maybe;
-
-namespace ipc {
-
-class AutoIPCStream;
-
-}  // namespace ipc
-
-namespace dom {
-
-class ClientInfoAndState;
-class LifeCycleEventCallback;
-class RemoteWorkerControllerChild;
-class ServiceWorkerCloneData;
-class ServiceWorkerRegistrationInfo;
-
-class ServiceWorkerPrivateImpl final : public ServiceWorkerPrivate::Inner,
-                                       public RemoteWorkerObserver {
- public:
-  NS_INLINE_DECL_REFCOUNTING(ServiceWorkerPrivateImpl, override);
-
-  explicit ServiceWorkerPrivateImpl(RefPtr<ServiceWorkerPrivate> aOuter);
-
-  nsresult Initialize();
-
-  RefPtr<GenericPromise> SetSkipWaitingFlag();
-
- private:
-  class RAIIActorPtrHolder;
-
-  ~ServiceWorkerPrivateImpl();
-
-  /**
-   * ServiceWorkerPrivate::Inner
-   */
-  nsresult SendMessageEvent(
-      RefPtr<ServiceWorkerCloneData>&& aData,
-      const ClientInfoAndState& aClientInfoAndState) override;
-
-  nsresult CheckScriptEvaluation(
-      RefPtr<LifeCycleEventCallback> aCallback) override;
-
-  nsresult SendLifeCycleEvent(
-      const nsAString& aEventName,
-      RefPtr<LifeCycleEventCallback> aCallback) override;
-
-  nsresult SendPushEvent(RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
-                         const nsAString& aMessageId,
-                         const Maybe<nsTArray<uint8_t>>& aData) override;
-
-  nsresult SendPushSubscriptionChangeEvent() override;
-
-  nsresult SendNotificationEvent(const nsAString& aEventName,
-                                 const nsAString& aID, const nsAString& aTitle,
-                                 const nsAString& aDir, const nsAString& aLang,
-                                 const nsAString& aBody, const nsAString& aTag,
-                                 const nsAString& aIcon, const nsAString& aData,
-                                 const nsAString& aBehavior,
-                                 const nsAString& aScope,
-                                 uint32_t aDisableOpenClickDelay) override;
-
-  nsresult SendFetchEvent(RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
-                          nsCOMPtr<nsIInterceptedChannel> aChannel,
-                          const nsAString& aClientId,
-                          const nsAString& aResultingClientId,
-                          bool aIsReload) override;
-
-  void TerminateWorker() override;
-
-  void UpdateState(ServiceWorkerState aState) override;
-
-  void NoteDeadOuter() override;
-
-  bool WorkerIsDead() const override;
-
-  /**
-   * RemoteWorkerObserver
-   */
-  void CreationFailed() override;
-
-  void CreationSucceeded() override;
-
-  void ErrorReceived(const ErrorValue& aError) override;
-
-  void Terminated() override;
-
-  // Refreshes only the parts of mRemoteWorkerData that may change over time.
-  nsresult RefreshRemoteWorkerData(
-      const RefPtr<ServiceWorkerRegistrationInfo>& aRegistration);
-
-  nsresult SpawnWorkerIfNeeded();
-
-  nsresult SendPushEventInternal(
-      RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-      ServiceWorkerPushEventOpArgs&& aArgs);
-
-  nsresult SendFetchEventInternal(
-      RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-      ServiceWorkerFetchEventOpArgs&& aArgs,
-      nsCOMPtr<nsIInterceptedChannel>&& aChannel,
-      UniquePtr<mozilla::ipc::AutoIPCStream>&& aAutoStream);
-
-  void Shutdown();
-
-  RefPtr<GenericNonExclusivePromise> ShutdownInternal();
-
-  nsresult ExecServiceWorkerOp(
-      ServiceWorkerOpArgs&& aArgs,
-      std::function<void(ServiceWorkerOpResult&&)>&& aSuccessCallback,
-      std::function<void()>&& aFailureCallback = [] {});
-
-  class PendingFunctionalEvent {
-   public:
-    PendingFunctionalEvent(
-        ServiceWorkerPrivateImpl* aOwner,
-        RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration);
-
-    virtual ~PendingFunctionalEvent();
-
-    virtual nsresult Send() = 0;
-
-   protected:
-    ServiceWorkerPrivateImpl* const MOZ_NON_OWNING_REF mOwner;
-    RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
-  };
-
-  class PendingPushEvent final : public PendingFunctionalEvent {
-   public:
-    PendingPushEvent(ServiceWorkerPrivateImpl* aOwner,
-                     RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-                     ServiceWorkerPushEventOpArgs&& aArgs);
-
-    nsresult Send() override;
-
-   private:
-    ServiceWorkerPushEventOpArgs mArgs;
-  };
-
-  class PendingFetchEvent final : public PendingFunctionalEvent {
-   public:
-    PendingFetchEvent(ServiceWorkerPrivateImpl* aOwner,
-                      RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
-                      ServiceWorkerFetchEventOpArgs&& aArgs,
-                      nsCOMPtr<nsIInterceptedChannel>&& aChannel,
-                      UniquePtr<AutoIPCStream>&& aAutoStream);
-
-    nsresult Send() override;
-
-    ~PendingFetchEvent();
-
-   private:
-    ServiceWorkerFetchEventOpArgs mArgs;
-    nsCOMPtr<nsIInterceptedChannel> mChannel;
-    UniquePtr<mozilla::ipc::AutoIPCStream> mAutoStream;
-  };
-
-  nsTArray<UniquePtr<PendingFunctionalEvent>> mPendingFunctionalEvents;
-
-  /**
-   * It's possible that there are still in-progress operations when a
-   * a termination operation is issued. In this case, it's important to keep
-   * the RemoteWorkerControllerChild actor alive until all pending operations
-   * have completed before destroying it with Send__delete__().
-   *
-   * RAIIActorPtrHolder holds a singular, owning reference to a
-   * RemoteWorkerControllerChild actor and is responsible for destroying the
-   * actor in its (i.e. the holder's) destructor. This implies that all
-   * in-progress operations must maintain a strong reference to their
-   * corresponding holders and release the reference once completed/canceled.
-   *
-   * Additionally a RAIIActorPtrHolder must be initialized with a non-null actor
-   * and cannot be moved or copied. Therefore, the identities of two held
-   * actors can be compared by simply comparing their holders' addresses.
-   */
-  class RAIIActorPtrHolder final {
-   public:
-    NS_INLINE_DECL_REFCOUNTING(RAIIActorPtrHolder)
-
-    explicit RAIIActorPtrHolder(
-        already_AddRefed<RemoteWorkerControllerChild> aActor);
-
-    RAIIActorPtrHolder(const RAIIActorPtrHolder& aOther) = delete;
-    RAIIActorPtrHolder& operator=(const RAIIActorPtrHolder& aOther) = delete;
-
-    RAIIActorPtrHolder(RAIIActorPtrHolder&& aOther) = delete;
-    RAIIActorPtrHolder& operator=(RAIIActorPtrHolder&& aOther) = delete;
-
-    RemoteWorkerControllerChild* operator->() const
-        MOZ_NO_ADDREF_RELEASE_ON_RETURN;
-
-    RemoteWorkerControllerChild* get() const;
-
-    RefPtr<GenericPromise> OnDestructor();
-
-   private:
-    ~RAIIActorPtrHolder();
-
-    MozPromiseHolder<GenericPromise> mDestructorPromiseHolder;
-
-    const RefPtr<RemoteWorkerControllerChild> mActor;
-  };
-
-  RefPtr<RAIIActorPtrHolder> mControllerChild;
-
-  RefPtr<ServiceWorkerPrivate> mOuter;
-
-  RemoteWorkerData mRemoteWorkerData;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_serviceworkerprivateimpl_h__
--- a/dom/serviceworkers/ServiceWorkerRegistration.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistration.cpp
@@ -7,17 +7,16 @@
 #include "ServiceWorkerRegistration.h"
 
 #include "mozilla/dom/DOMMozPromiseRequestHolder.h"
 #include "mozilla/dom/Notification.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PushManager.h"
 #include "mozilla/dom/ServiceWorker.h"
 #include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
-#include "mozilla/dom/ServiceWorkerUtils.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsPrimitives.h"
 #include "nsPIDOMWindow.h"
 #include "RemoteServiceWorkerRegistrationImpl.h"
 #include "ServiceWorkerRegistrationImpl.h"
 
 namespace mozilla {
@@ -195,51 +194,16 @@ already_AddRefed<Promise> ServiceWorkerR
     return nullptr;
   }
 
   RefPtr<Promise> outer = Promise::Create(global, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  /**
-   * `ServiceWorker` objects are not exposed on worker threads yet, so calling
-   * `ServiceWorkerRegistration::Get{Installing,Waiting,Active}` won't work.
-   */
-  const bool hasNewestWorker = mDescriptor.GetInstalling() ||
-                               mDescriptor.GetWaiting() ||
-                               mDescriptor.GetActive();
-
-  /**
-   * If newestWorker is null, return a promise rejected with an
-   * "InvalidStateError" DOMException and abort these steps.
-   */
-  if (!hasNewestWorker) {
-    outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
-    return outer.forget();
-  }
-
-  /**
-   * If the context object’s relevant settings object’s global object
-   * globalObject is a ServiceWorkerGlobalScope object, and globalObject’s
-   * associated service worker's state is "installing", return a promise
-   * rejected with an "InvalidStateError" DOMException and abort these steps.
-   */
-  if (!NS_IsMainThread()) {
-    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-    MOZ_ASSERT(workerPrivate);
-
-    if (workerPrivate->IsServiceWorker() &&
-        (workerPrivate->GetServiceWorkerDescriptor().State() ==
-         ServiceWorkerState::Installing)) {
-      outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
-      return outer.forget();
-    }
-  }
-
   RefPtr<ServiceWorkerRegistration> self = this;
 
   mInner->Update(
       [outer, self](const ServiceWorkerRegistrationDescriptor& aDesc) {
         nsIGlobalObject* global = self->GetParentObject();
         MOZ_DIAGNOSTIC_ASSERT(global);
         RefPtr<ServiceWorkerRegistration> ref =
             global->GetOrCreateServiceWorkerRegistration(aDesc);
--- a/dom/serviceworkers/ServiceWorkerRegistrationChild.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistrationChild.cpp
@@ -2,17 +2,16 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "ServiceWorkerRegistrationChild.h"
 
 #include "RemoteServiceWorkerRegistrationImpl.h"
-#include "mozilla/dom/WorkerRef.h"
 
 namespace mozilla {
 namespace dom {
 
 using mozilla::ipc::IPCResult;
 
 void ServiceWorkerRegistrationChild::ActorDestroy(ActorDestroyReason aReason) {
   mIPCWorkerRef = nullptr;
--- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.cpp
@@ -289,41 +289,33 @@ ServiceWorkerRegistrationInfo::GetServic
     serviceWorker = mWaitingWorker;
   } else if (mActiveWorker && mActiveWorker->ID() == aId) {
     serviceWorker = mActiveWorker;
   }
 
   return serviceWorker.forget();
 }
 
-void ServiceWorkerRegistrationInfo::TryToActivateAsync(
-    TryToActivateCallback&& aCallback) {
+void ServiceWorkerRegistrationInfo::TryToActivateAsync() {
   MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(
-      NewRunnableMethod<StoreCopyPassByRRef<TryToActivateCallback>>(
-          "ServiceWorkerRegistrationInfo::TryToActivate", this,
-          &ServiceWorkerRegistrationInfo::TryToActivate,
-          std::move(aCallback))));
+      NewRunnableMethod("ServiceWorkerRegistrationInfo::TryToActivate", this,
+                        &ServiceWorkerRegistrationInfo::TryToActivate)));
 }
 
 /*
  * TryToActivate should not be called directly, use TryToActivateAsync instead.
  */
-void ServiceWorkerRegistrationInfo::TryToActivate(
-    TryToActivateCallback&& aCallback) {
+void ServiceWorkerRegistrationInfo::TryToActivate() {
   MOZ_ASSERT(NS_IsMainThread());
   bool controlling = IsControllingClients();
   bool skipWaiting = mWaitingWorker && mWaitingWorker->SkipWaitingFlag();
   bool idle = IsIdle();
   if (idle && (!controlling || skipWaiting)) {
     Activate();
   }
-
-  if (aCallback) {
-    aCallback();
-  }
 }
 
 void ServiceWorkerRegistrationInfo::Activate() {
   if (!mWaitingWorker) {
     return;
   }
 
   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
@@ -704,24 +696,18 @@ ServiceWorkerRegistrationInfo::Descripto
 }
 
 uint64_t ServiceWorkerRegistrationInfo::Id() const { return mDescriptor.Id(); }
 
 uint64_t ServiceWorkerRegistrationInfo::Version() const {
   return mDescriptor.Version();
 }
 
-uint32_t ServiceWorkerRegistrationInfo::GetUpdateDelay(
-    const bool aWithMultiplier) {
+uint32_t ServiceWorkerRegistrationInfo::GetUpdateDelay() {
   uint32_t delay = Preferences::GetInt("dom.serviceWorkers.update_delay", 1000);
-
-  if (!aWithMultiplier) {
-    return delay;
-  }
-
   // This can potentially happen if you spam registration->Update(). We don't
   // want to wrap to a lower value.
   if (mDelayMultiplier >= INT_MAX / (delay ? delay : 1)) {
     return INT_MAX;
   }
 
   delay *= mDelayMultiplier;
 
--- a/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
+++ b/dom/serviceworkers/ServiceWorkerRegistrationInfo.h
@@ -2,18 +2,16 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_dom_serviceworkerregistrationinfo_h
 #define mozilla_dom_serviceworkerregistrationinfo_h
 
-#include <functional>
-
 #include "mozilla/dom/ServiceWorkerInfo.h"
 #include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
 #include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
 #include "nsProxyRelease.h"
 #include "nsTObserverArray.h"
 
 namespace mozilla {
 namespace dom {
@@ -65,18 +63,16 @@ class ServiceWorkerRegistrationInfo fina
   bool mUnregistered;
 
   bool mCorrupt;
 
  public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
 
-  typedef std::function<void()> TryToActivateCallback;
-
   ServiceWorkerRegistrationInfo(const nsACString& aScope,
                                 nsIPrincipal* aPrincipal,
                                 ServiceWorkerUpdateViaCache aUpdateViaCache);
 
   void AddInstance(ServiceWorkerRegistrationListener* aInstance,
                    const ServiceWorkerRegistrationDescriptor& aDescriptor);
 
   void RemoveInstance(ServiceWorkerRegistrationListener* aInstance);
@@ -119,19 +115,19 @@ class ServiceWorkerRegistrationInfo fina
   }
 
   void Clear();
 
   void ClearAsCorrupt();
 
   bool IsCorrupt() const;
 
-  void TryToActivateAsync(TryToActivateCallback&& aCallback = nullptr);
+  void TryToActivateAsync();
 
-  void TryToActivate(TryToActivateCallback&& aCallback);
+  void TryToActivate();
 
   void Activate();
 
   void FinishActivate(bool aSuccess);
 
   void RefreshLastUpdateCheckTime();
 
   bool IsLastUpdateCheckTimeOverOneDay() const;
@@ -196,17 +192,17 @@ class ServiceWorkerRegistrationInfo fina
   void SetLastUpdateTime(const int64_t aTime);
 
   const ServiceWorkerRegistrationDescriptor& Descriptor() const;
 
   uint64_t Id() const;
 
   uint64_t Version() const;
 
-  uint32_t GetUpdateDelay(const bool aWithMultiplier = true);
+  uint32_t GetUpdateDelay();
 
   void FireUpdateFound();
 
   void NotifyCleared();
 
   void ClearWhenIdle();
 
  private:
--- a/dom/serviceworkers/ServiceWorkerRegistrationProxy.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistrationProxy.cpp
@@ -26,19 +26,16 @@ class ServiceWorkerRegistrationProxy::De
 
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITIMERCALLBACK
 
   DelayedUpdate(RefPtr<ServiceWorkerRegistrationProxy>&& aProxy,
                 RefPtr<ServiceWorkerRegistrationPromise::Private>&& aPromise,
                 uint32_t delay);
-
-  void ChainTo(RefPtr<ServiceWorkerRegistrationPromise::Private> aPromise);
-
   void Reject();
 };
 
 ServiceWorkerRegistrationProxy::~ServiceWorkerRegistrationProxy() {
   // Any thread
   MOZ_DIAGNOSTIC_ASSERT(!mActor);
   MOZ_DIAGNOSTIC_ASSERT(!mReg);
 }
@@ -262,43 +259,30 @@ ServiceWorkerRegistrationProxy::DelayedU
   mProxy->mDelayedUpdate = this;
   Result<nsCOMPtr<nsITimer>, nsresult> result =
       NS_NewTimerWithCallback(this, delay, nsITimer::TYPE_ONE_SHOT,
                               SystemGroup::EventTargetFor(TaskCategory::Other));
   mTimer = result.unwrapOr(nullptr);
   MOZ_DIAGNOSTIC_ASSERT(mTimer);
 }
 
-void ServiceWorkerRegistrationProxy::DelayedUpdate::ChainTo(
-    RefPtr<ServiceWorkerRegistrationPromise::Private> aPromise) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(mProxy->mDelayedUpdate == this);
-  MOZ_ASSERT(mPromise);
-
-  mPromise->ChainTo(aPromise.forget(), __func__);
-}
-
 void ServiceWorkerRegistrationProxy::DelayedUpdate::Reject() {
   MOZ_DIAGNOSTIC_ASSERT(mPromise);
   if (mTimer) {
     mTimer->Cancel();
     mTimer = nullptr;
   }
   mPromise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
 }
 
 NS_IMETHODIMP
 ServiceWorkerRegistrationProxy::DelayedUpdate::Notify(nsITimer* aTimer) {
-  // Already shutting down.
-  if (mProxy->mDelayedUpdate != this) {
-    return NS_OK;
-  }
-
   auto scopeExit = MakeScopeExit(
       [&] { mPromise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); });
+  MOZ_DIAGNOSTIC_ASSERT((mProxy->mDelayedUpdate == this));
 
   NS_ENSURE_TRUE(mProxy->mReg, NS_ERROR_FAILURE);
 
   RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
   NS_ENSURE_TRUE(swm, NS_ERROR_FAILURE);
 
   RefPtr<UpdateCallback> cb = new UpdateCallback(std::move(mPromise));
   swm->Update(mProxy->mReg->Principal(), mProxy->mReg->Scope(), cb);
@@ -320,31 +304,24 @@ ServiceWorkerRegistrationProxy::Update()
 
   nsCOMPtr<nsIRunnable> r =
       NS_NewRunnableFunction(__func__, [self, promise]() mutable {
         auto scopeExit = MakeScopeExit(
             [&] { promise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); });
 
         // Get the delay value for the update
         NS_ENSURE_TRUE_VOID(self->mReg);
-        uint32_t delay = self->mReg->GetUpdateDelay(false);
+        uint32_t delay = self->mReg->GetUpdateDelay();
 
         // If the delay value does not equal to 0, create a timer and a timer
         // callback to perform the delayed update. Otherwise, update directly.
         if (delay) {
-          if (self->mDelayedUpdate) {
-            // NOTE: if we `ChainTo(),` there will ultimately be a single
-            // update, and this update will resolve all promises that were
-            // issued while the update's timer was ticking down.
-            self->mDelayedUpdate->ChainTo(std::move(promise));
-          } else {
-            RefPtr<ServiceWorkerRegistrationProxy::DelayedUpdate> du =
-                new ServiceWorkerRegistrationProxy::DelayedUpdate(
-                    std::move(self), std::move(promise), delay);
-          }
+          RefPtr<ServiceWorkerRegistrationProxy::DelayedUpdate> du =
+              new ServiceWorkerRegistrationProxy::DelayedUpdate(
+                  std::move(self), std::move(promise), delay);
         } else {
           RefPtr<ServiceWorkerManager> swm =
               ServiceWorkerManager::GetInstance();
           NS_ENSURE_TRUE_VOID(swm);
 
           RefPtr<UpdateCallback> cb = new UpdateCallback(std::move(promise));
           swm->Update(self->mReg->Principal(), self->mReg->Scope(), cb);
         }
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerShutdownBlocker.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "ServiceWorkerShutdownBlocker.h"
-
-#include <utility>
-
-#include "MainThreadUtils.h"
-#include "nsDebug.h"
-#include "nsError.h"
-#include "nsIWritablePropertyBag2.h"
-#include "nsThreadUtils.h"
-
-#include "mozilla/Assertions.h"
-#include "mozilla/RefPtr.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ISUPPORTS(ServiceWorkerShutdownBlocker, nsIAsyncShutdownBlocker)
-
-NS_IMETHODIMP ServiceWorkerShutdownBlocker::GetName(nsAString& aNameOut) {
-  aNameOut = NS_LITERAL_STRING(
-      "ServiceWorkerShutdownBlocker: shutting down Service Workers");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ServiceWorkerShutdownBlocker::BlockShutdown(nsIAsyncShutdownClient* aClient) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(!mShutdownClient);
-
-  mShutdownClient = aClient;
-  MaybeUnblockShutdown();
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP ServiceWorkerShutdownBlocker::GetState(nsIPropertyBag** aBagOut) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aBagOut);
-
-  nsCOMPtr<nsIWritablePropertyBag2> propertyBag =
-      do_CreateInstance("@mozilla.org/hash-property-bag;1");
-
-  if (NS_WARN_IF(!propertyBag)) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  nsresult rv = propertyBag->SetPropertyAsBool(
-      NS_LITERAL_STRING("acceptingPromises"), IsAcceptingPromises());
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  rv = propertyBag->SetPropertyAsUint32(NS_LITERAL_STRING("pendingPromises"),
-                                        GetPendingPromises());
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  propertyBag.forget(aBagOut);
-
-  return NS_OK;
-}
-
-/* static */ already_AddRefed<ServiceWorkerShutdownBlocker>
-ServiceWorkerShutdownBlocker::CreateAndRegisterOn(
-    nsIAsyncShutdownClient* aShutdownBarrier) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(aShutdownBarrier);
-
-  RefPtr<ServiceWorkerShutdownBlocker> blocker =
-      new ServiceWorkerShutdownBlocker();
-
-  nsresult rv = aShutdownBarrier->AddBlocker(
-      blocker.get(), NS_LITERAL_STRING(__FILE__), __LINE__,
-      NS_LITERAL_STRING("Service Workers shutdown"));
-
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return nullptr;
-  }
-
-  return blocker.forget();
-}
-
-void ServiceWorkerShutdownBlocker::WaitOnPromise(
-    GenericNonExclusivePromise* aPromise) {
-  AssertIsOnMainThread();
-  MOZ_DIAGNOSTIC_ASSERT(IsAcceptingPromises());
-  MOZ_ASSERT(aPromise);
-
-  ++mState.as<AcceptingPromises>().mPendingPromises;
-
-  RefPtr<ServiceWorkerShutdownBlocker> self = this;
-
-  aPromise->Then(GetCurrentThreadSerialEventTarget(), __func__,
-                 [self = std::move(self)](
-                     const GenericNonExclusivePromise::ResolveOrRejectValue&) {
-                   if (!self->PromiseSettled()) {
-                     self->MaybeUnblockShutdown();
-                   }
-                 });
-}
-
-void ServiceWorkerShutdownBlocker::StopAcceptingPromises() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(IsAcceptingPromises());
-
-  mState = AsVariant(NotAcceptingPromises(mState.as<AcceptingPromises>()));
-}
-
-ServiceWorkerShutdownBlocker::ServiceWorkerShutdownBlocker()
-    : mState(VariantType<AcceptingPromises>()) {
-  AssertIsOnMainThread();
-}
-
-ServiceWorkerShutdownBlocker::~ServiceWorkerShutdownBlocker() {
-  MOZ_ASSERT(!IsAcceptingPromises());
-  MOZ_ASSERT(!GetPendingPromises());
-  MOZ_ASSERT(!mShutdownClient);
-}
-
-void ServiceWorkerShutdownBlocker::MaybeUnblockShutdown() {
-  AssertIsOnMainThread();
-
-  if (!mShutdownClient || IsAcceptingPromises() || GetPendingPromises()) {
-    return;
-  }
-
-  mShutdownClient->RemoveBlocker(this);
-  mShutdownClient = nullptr;
-}
-
-uint32_t ServiceWorkerShutdownBlocker::PromiseSettled() {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(GetPendingPromises());
-
-  if (IsAcceptingPromises()) {
-    return --mState.as<AcceptingPromises>().mPendingPromises;
-  }
-
-  return --mState.as<NotAcceptingPromises>().mPendingPromises;
-}
-
-bool ServiceWorkerShutdownBlocker::IsAcceptingPromises() const {
-  AssertIsOnMainThread();
-
-  return mState.is<AcceptingPromises>();
-}
-
-uint32_t ServiceWorkerShutdownBlocker::GetPendingPromises() const {
-  AssertIsOnMainThread();
-
-  if (IsAcceptingPromises()) {
-    return mState.as<AcceptingPromises>().mPendingPromises;
-  }
-
-  return mState.as<NotAcceptingPromises>().mPendingPromises;
-}
-
-ServiceWorkerShutdownBlocker::NotAcceptingPromises::NotAcceptingPromises(
-    AcceptingPromises aPreviousState)
-    : mPendingPromises(aPreviousState.mPendingPromises) {
-  AssertIsOnMainThread();
-}
-
-}  // namespace dom
-}  // namespace mozilla
deleted file mode 100644
--- a/dom/serviceworkers/ServiceWorkerShutdownBlocker.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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/. */
-
-#ifndef mozilla_dom_serviceworkershutdownblocker_h__
-#define mozilla_dom_serviceworkershutdownblocker_h__
-
-#include "nsCOMPtr.h"
-#include "nsIAsyncShutdown.h"
-#include "nsISupportsImpl.h"
-
-#include "mozilla/MozPromise.h"
-
-namespace mozilla {
-namespace dom {
-
-/**
- * Main thread only.
- */
-class ServiceWorkerShutdownBlocker final : public nsIAsyncShutdownBlocker {
- public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIASYNCSHUTDOWNBLOCKER
-
-  /**
-   * Returns the registered shutdown blocker if registration succeeded and
-   * nullptr otherwise.
-   */
-  static already_AddRefed<ServiceWorkerShutdownBlocker> CreateAndRegisterOn(
-      nsIAsyncShutdownClient* aShutdownBarrier);
-
-  /**
-   * Blocks shutdown until `aPromise` settles.
-   *
-   * Can be called multiple times, and shutdown will be blocked until all the
-   * calls' promises settle, but all of these calls must happen before
-   * `StopAcceptingPromises()` is called (assertions will enforce this).
-   */
-  void WaitOnPromise(GenericNonExclusivePromise* aPromise);
-
-  /**
-   * Once this is called, shutdown will be blocked until all promises
-   * passed to `WaitOnPromise()` settle, and there must be no more calls to
-   * `WaitOnPromise()` (assertions will enforce this).
-   */
-  void StopAcceptingPromises();
-
- private:
-  ServiceWorkerShutdownBlocker();
-
-  ~ServiceWorkerShutdownBlocker();
-
-  /**
-   * No-op if any of the following are true:
-   * 1) `BlockShutdown()` hasn't been called yet, or
-   * 2) `StopAcceptingPromises()` hasn't been called yet, or
-   * 3) `StopAcceptingPromises()` HAS been called, but there are still pending
-   *    promises.
-   */
-  void MaybeUnblockShutdown();
-
-  /**
-   * Returns the remaining pending promise count (i.e. excluding the promise
-   * that just settled).
-   */
-  uint32_t PromiseSettled();
-
-  bool IsAcceptingPromises() const;
-
-  uint32_t GetPendingPromises() const;
-
-  struct AcceptingPromises {
-    uint32_t mPendingPromises = 0;
-  };
-
-  struct NotAcceptingPromises {
-    explicit NotAcceptingPromises(AcceptingPromises aPreviousState);
-
-    uint32_t mPendingPromises = 0;
-  };
-
-  Variant<AcceptingPromises, NotAcceptingPromises> mState;
-
-  nsCOMPtr<nsIAsyncShutdownClient> mShutdownClient;
-};
-
-}  // namespace dom
-}  // namespace mozilla
-
-#endif  // mozilla_dom_serviceworkershutdownblocker_h__
--- a/dom/serviceworkers/moz.build
+++ b/dom/serviceworkers/moz.build
@@ -4,46 +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/.
 
 with Files("**"):
     BUG_COMPONENT = ("Core", "DOM: Service Workers")
 
 # Public stuff.
 EXPORTS.mozilla.dom += [
-    'FetchEventOpChild.h',
-    'FetchEventOpParent.h',
-    'FetchEventOpProxyChild.h',
-    'FetchEventOpProxyParent.h',
     'ServiceWorker.h',
     'ServiceWorkerActors.h',
-    'ServiceWorkerCloneData.h',
     'ServiceWorkerContainer.h',
     'ServiceWorkerDescriptor.h',
     'ServiceWorkerEvents.h',
     'ServiceWorkerInfo.h',
     'ServiceWorkerInterceptController.h',
     'ServiceWorkerIPCUtils.h',
     'ServiceWorkerManager.h',
     'ServiceWorkerManagerChild.h',
     'ServiceWorkerManagerParent.h',
-    'ServiceWorkerOp.h',
-    'ServiceWorkerOpPromise.h',
     'ServiceWorkerRegistrar.h',
     'ServiceWorkerRegistration.h',
     'ServiceWorkerRegistrationDescriptor.h',
     'ServiceWorkerRegistrationInfo.h',
     'ServiceWorkerUtils.h',
 ]
 
 UNIFIED_SOURCES += [
-    'FetchEventOpChild.cpp',
-    'FetchEventOpParent.cpp',
-    'FetchEventOpProxyChild.cpp',
-    'FetchEventOpProxyParent.cpp',
     'RemoteServiceWorkerContainerImpl.cpp',
     'RemoteServiceWorkerImpl.cpp',
     'RemoteServiceWorkerRegistrationImpl.cpp',
     'ServiceWorker.cpp',
     'ServiceWorkerActors.cpp',
     'ServiceWorkerChild.cpp',
     'ServiceWorkerCloneData.cpp',
     'ServiceWorkerContainer.cpp',
@@ -57,60 +46,53 @@ UNIFIED_SOURCES += [
     'ServiceWorkerInfo.cpp',
     'ServiceWorkerInterceptController.cpp',
     'ServiceWorkerJob.cpp',
     'ServiceWorkerJobQueue.cpp',
     'ServiceWorkerManager.cpp',
     'ServiceWorkerManagerChild.cpp',
     'ServiceWorkerManagerParent.cpp',
     'ServiceWorkerManagerService.cpp',
-    'ServiceWorkerOp.cpp',
     'ServiceWorkerParent.cpp',
     'ServiceWorkerPrivate.cpp',
-    'ServiceWorkerPrivateImpl.cpp',
     'ServiceWorkerProxy.cpp',
     'ServiceWorkerRegisterJob.cpp',
     'ServiceWorkerRegistrar.cpp',
     'ServiceWorkerRegistration.cpp',
     'ServiceWorkerRegistrationChild.cpp',
     'ServiceWorkerRegistrationDescriptor.cpp',
     'ServiceWorkerRegistrationImpl.cpp',
     'ServiceWorkerRegistrationInfo.cpp',
     'ServiceWorkerRegistrationParent.cpp',
     'ServiceWorkerRegistrationProxy.cpp',
     'ServiceWorkerScriptCache.cpp',
-    'ServiceWorkerShutdownBlocker.cpp',
     'ServiceWorkerUnregisterCallback.cpp',
     'ServiceWorkerUnregisterJob.cpp',
     'ServiceWorkerUpdateJob.cpp',
     'ServiceWorkerUpdaterChild.cpp',
     'ServiceWorkerUpdaterParent.cpp',
     'ServiceWorkerUtils.cpp',
 ]
 
 IPDL_SOURCES += [
     'IPCServiceWorkerDescriptor.ipdlh',
     'IPCServiceWorkerRegistrationDescriptor.ipdlh',
-    'PFetchEventOp.ipdl',
-    'PFetchEventOpProxy.ipdl',
     'PServiceWorker.ipdl',
     'PServiceWorkerContainer.ipdl',
     'PServiceWorkerManager.ipdl',
     'PServiceWorkerRegistration.ipdl',
     'PServiceWorkerUpdater.ipdl',
-    'ServiceWorkerOpArgs.ipdlh',
     'ServiceWorkerRegistrarTypes.ipdlh',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
-    '/extensions/permissions',
     '/js/xpconnect/loader',
 ]
 
 MOCHITEST_MANIFESTS += [
     'test/mochitest.ini',
 ]
 
 MOCHITEST_CHROME_MANIFESTS += [
--- a/dom/workers/WorkerError.cpp
+++ b/dom/workers/WorkerError.cpp
@@ -6,17 +6,16 @@
 
 #include "WorkerError.h"
 
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/ErrorEventBinding.h"
 #include "mozilla/dom/RemoteWorkerChild.h"
 #include "mozilla/dom/ServiceWorkerManager.h"
-#include "mozilla/dom/ServiceWorkerUtils.h"
 #include "mozilla/dom/SimpleGlobalObject.h"
 #include "mozilla/dom/WorkerDebuggerGlobalScopeBinding.h"
 #include "mozilla/dom/WorkerGlobalScopeBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "nsGlobalWindowInner.h"
 #include "nsIConsoleService.h"
 #include "nsScriptError.h"
 #include "WorkerRunnable.h"
@@ -76,38 +75,25 @@ class ReportErrorRunnable final : public
                                            /* isErrorEvent */ true);
         return true;
       }
 
       // Service workers do not have a main thread parent global, so normal
       // worker error reporting will crash.  Instead, pass the error to
       // the ServiceWorkerManager to report on any controlled documents.
       if (aWorkerPrivate->IsServiceWorker()) {
-        if (ServiceWorkerParentInterceptEnabled()) {
-          RefPtr<RemoteWorkerChild> actor(
-              aWorkerPrivate->GetRemoteWorkerControllerWeakRef());
-
-          Unused << NS_WARN_IF(!actor);
-
-          if (actor) {
-            actor->ErrorPropagationOnMainThread(nullptr, false);
-          }
-
-        } else {
-          RefPtr<ServiceWorkerManager> swm =
-              ServiceWorkerManager::GetInstance();
-          if (swm) {
-            swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
-                             aWorkerPrivate->ServiceWorkerScope(),
-                             aWorkerPrivate->ScriptURL(), EmptyString(),
-                             EmptyString(), EmptyString(), 0, 0, JSREPORT_ERROR,
-                             JSEXN_ERR);
-          }
+        RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+        if (swm) {
+          swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
+                           aWorkerPrivate->ServiceWorkerScope(),
+                           aWorkerPrivate->ScriptURL(), mReport->mMessage,
+                           mReport->mFilename, mReport->mLine,
+                           mReport->mLineNumber, mReport->mColumnNumber,
+                           mReport->mFlags, mReport->mExnType);
         }
-
         return true;
       }
 
       // The innerWindowId is only required if we are going to ReportError
       // below, which is gated on this condition. The inner window correctness
       // check is only going to succeed when the worker is accepting events.
       if (workerIsAcceptingEvents) {
         aWorkerPrivate->AssertInnerWindowIsCorrect();
@@ -168,37 +154,24 @@ class ReportGenericErrorRunnable final :
 
     if (aWorkerPrivate->IsSharedWorker()) {
       aWorkerPrivate->GetRemoteWorkerController()->ErrorPropagationOnMainThread(
           nullptr, false);
       return true;
     }
 
     if (aWorkerPrivate->IsServiceWorker()) {
-      if (ServiceWorkerParentInterceptEnabled()) {
-        RefPtr<RemoteWorkerChild> actor(
-            aWorkerPrivate->GetRemoteWorkerControllerWeakRef());
-
-        Unused << NS_WARN_IF(!actor);
-
-        if (actor) {
-          actor->ErrorPropagationOnMainThread(nullptr, false);
-        }
-
-      } else {
-        RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
-        if (swm) {
-          swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
-                           aWorkerPrivate->ServiceWorkerScope(),
-                           aWorkerPrivate->ScriptURL(), EmptyString(),
-                           EmptyString(), EmptyString(), 0, 0, JSREPORT_ERROR,
-                           JSEXN_ERR);
-        }
+      RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
+      if (swm) {
+        swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
+                         aWorkerPrivate->ServiceWorkerScope(),
+                         aWorkerPrivate->ScriptURL(), EmptyString(),
+                         EmptyString(), EmptyString(), 0, 0, JSREPORT_ERROR,
+                         JSEXN_ERR);
       }
-
       return true;
     }
 
     if (!aWorkerPrivate->IsAcceptingEvents()) {
       return true;
     }
 
     RefPtr<mozilla::dom::EventTarget> parentEventTarget =
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -31,17 +31,16 @@
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/MessagePortBinding.h"
 #include "mozilla/dom/nsCSPContext.h"
 #include "mozilla/dom/nsCSPUtils.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PerformanceStorageWorker.h"
 #include "mozilla/dom/PromiseDebugging.h"
 #include "mozilla/dom/RemoteWorkerChild.h"
-#include "mozilla/dom/RemoteWorkerService.h"
 #include "mozilla/dom/TimeoutHandler.h"
 #include "mozilla/dom/WorkerBinding.h"
 #include "mozilla/StorageAccess.h"
 #include "mozilla/ThreadEventQueue.h"
 #include "mozilla/ThrottledEventQueue.h"
 #include "mozilla/TimelineConsumers.h"
 #include "mozilla/WorkerTimelineMarker.h"
 #include "nsCycleCollector.h"
@@ -49,17 +48,16 @@
 #include "nsNetUtil.h"
 #include "nsIMemoryReporter.h"
 #include "nsIPermissionManager.h"
 #include "nsIRandomGenerator.h"
 #include "nsIScriptError.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsPrintfCString.h"
-#include "nsProxyRelease.h"
 #include "nsQueryObject.h"
 #include "nsRFPService.h"
 #include "nsSandboxFlags.h"
 #include "nsUTF8Utils.h"
 
 #include "RuntimeService.h"
 #include "ScriptLoader.h"
 #include "mozilla/dom/ServiceWorkerEvents.h"
@@ -4844,50 +4842,16 @@ void WorkerPrivate::SetRemoteWorkerContr
 }
 
 RemoteWorkerChild* WorkerPrivate::GetRemoteWorkerController() {
   AssertIsOnMainThread();
   MOZ_ASSERT(mRemoteWorkerController);
   return mRemoteWorkerController;
 }
 
-void WorkerPrivate::SetRemoteWorkerControllerWeakRef(
-    ThreadSafeWeakPtr<RemoteWorkerChild> aWeakRef) {
-  MOZ_ASSERT(aWeakRef);
-  MOZ_ASSERT(!mRemoteWorkerControllerWeakRef);
-  MOZ_ASSERT(IsServiceWorker());
-
-  mRemoteWorkerControllerWeakRef = std::move(aWeakRef);
-}
-
-ThreadSafeWeakPtr<RemoteWorkerChild>
-WorkerPrivate::GetRemoteWorkerControllerWeakRef() {
-  MOZ_ASSERT(IsServiceWorker());
-  return mRemoteWorkerControllerWeakRef;
-}
-
-RefPtr<GenericPromise> WorkerPrivate::SetServiceWorkerSkipWaitingFlag() {
-  AssertIsOnWorkerThread();
-  MOZ_ASSERT(IsServiceWorker());
-
-  RefPtr<RemoteWorkerChild> rwc(mRemoteWorkerControllerWeakRef);
-
-  if (!rwc) {
-    return GenericPromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR, __func__);
-  }
-
-  RefPtr<GenericPromise> promise =
-      rwc->MaybeSendSetServiceWorkerSkipWaitingFlag();
-
-  NS_ProxyRelease("WorkerPrivate::mRemoteWorkerControllerWeakRef",
-                  RemoteWorkerService::Thread(), rwc.forget());
-
-  return promise;
-}
-
 nsAString& WorkerPrivate::Id() {
   AssertIsOnMainThread();
 
   if (mID.IsEmpty()) {
     nsresult rv;
     nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
         do_GetService("@mozilla.org/uuid-generator;1", &rv);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -7,27 +7,24 @@
 #ifndef mozilla_dom_workers_workerprivate_h__
 #define mozilla_dom_workers_workerprivate_h__
 
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/dom/WorkerStatus.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/CondVar.h"
 #include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/MozPromise.h"
 #include "mozilla/RelativeTimeline.h"
 #include "mozilla/StorageAccess.h"
-#include "mozilla/ThreadSafeWeakPtr.h"
 #include "nsContentUtils.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIEventTarget.h"
 #include "nsTObserverArray.h"
 
 #include "js/ContextOptions.h"
-#include "mozilla/dom/RemoteWorkerChild.h"
 #include "mozilla/dom/Worker.h"
 #include "mozilla/dom/WorkerLoadInfo.h"
 #include "mozilla/dom/workerinternals/JSSettings.h"
 #include "mozilla/dom/workerinternals/Queue.h"
 #include "mozilla/PerformanceCounter.h"
 #include "mozilla/ThreadBound.h"
 
 class nsIThreadInternal;
@@ -41,16 +38,17 @@ namespace dom {
 enum WorkerType { WorkerTypeDedicated, WorkerTypeShared, WorkerTypeService };
 
 class ClientInfo;
 class ClientSource;
 class Function;
 class MessagePort;
 class MessagePortIdentifier;
 class PerformanceStorage;
+class RemoteWorkerChild;
 class TimeoutHandler;
 class WorkerControlRunnable;
 class WorkerCSPEventListener;
 class WorkerDebugger;
 class WorkerDebuggerGlobalScope;
 class WorkerErrorReport;
 class WorkerEventTarget;
 class WorkerGlobalScope;
@@ -786,23 +784,16 @@ class WorkerPrivate : public RelativeTim
     // any thread
     mLoadingWorkerScript = aLoadingWorkerScript;
   }
 
   RemoteWorkerChild* GetRemoteWorkerController();
 
   void SetRemoteWorkerController(RemoteWorkerChild* aController);
 
-  void SetRemoteWorkerControllerWeakRef(
-      ThreadSafeWeakPtr<RemoteWorkerChild> aWeakRef);
-
-  ThreadSafeWeakPtr<RemoteWorkerChild> GetRemoteWorkerControllerWeakRef();
-
-  RefPtr<GenericPromise> SetServiceWorkerSkipWaitingFlag();
-
   // We can assume that an nsPIDOMWindow will be available for Freeze, Thaw
   // as these are only used for globals going in and out of the bfcache.
   bool Freeze(nsPIDOMWindowInner* aWindow);
 
   bool Thaw(nsPIDOMWindowInner* aWindow);
 
   void PropagateFirstPartyStorageAccessGranted();
 
@@ -1069,19 +1060,16 @@ class WorkerPrivate : public RelativeTim
   RefPtr<WorkerCSPEventListener> mCSPEventListener;
 
   // Protected by mMutex.
   nsTArray<RefPtr<WorkerRunnable>> mPreStartRunnables;
 
   // Only touched on the parent thread. This is set only if IsSharedWorker().
   RefPtr<RemoteWorkerChild> mRemoteWorkerController;
 
-  // This is set only if IsServiceWorker().
-  ThreadSafeWeakPtr<RemoteWorkerChild> mRemoteWorkerControllerWeakRef;
-
   JS::UniqueChars mDefaultLocale;  // nulled during worker JSContext init
   TimeStamp mKillTime;
   WorkerStatus mParentStatus;
   WorkerStatus mStatus;
 
   // This is touched on parent thread only, but it can be read on a different
   // thread before crashing because hanging.
   Atomic<uint64_t> mBusyCount;
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -20,17 +20,16 @@
 #include "mozilla/dom/FunctionBinding.h"
 #include "mozilla/dom/IDBFactory.h"
 #include "mozilla/dom/ImageBitmap.h"
 #include "mozilla/dom/ImageBitmapBinding.h"
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseWorkerProxy.h"
 #include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
-#include "mozilla/dom/ServiceWorkerUtils.h"
 #include "mozilla/dom/SharedWorkerGlobalScopeBinding.h"
 #include "mozilla/dom/SimpleGlobalObject.h"
 #include "mozilla/dom/TimeoutHandler.h"
 #include "mozilla/dom/WorkerDebuggerGlobalScopeBinding.h"
 #include "mozilla/dom/WorkerGlobalScopeBinding.h"
 #include "mozilla/dom/WorkerLocation.h"
 #include "mozilla/dom/WorkerNavigator.h"
 #include "mozilla/dom/cache/CacheStorage.h"
@@ -854,31 +853,16 @@ already_AddRefed<Promise> ServiceWorkerG
   mWorkerPrivate->AssertIsOnWorkerThread();
   MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());
 
   RefPtr<Promise> promise = Promise::Create(this, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  if (ServiceWorkerParentInterceptEnabled()) {
-    mWorkerPrivate->SetServiceWorkerSkipWaitingFlag()->Then(
-        GetCurrentThreadSerialEventTarget(), __func__,
-        [promise](bool aOk) {
-          Unused << NS_WARN_IF(!aOk);
-          promise->MaybeResolveWithUndefined();
-        },
-        [promise](nsresult aRv) {
-          MOZ_ASSERT(NS_FAILED(aRv));
-          promise->MaybeResolveWithUndefined();
-        });
-
-    return promise.forget();
-  }
-
   RefPtr<PromiseWorkerProxy> promiseProxy =
       PromiseWorkerProxy::Create(mWorkerPrivate, promise);
   if (!promiseProxy) {
     promise->MaybeResolveWithUndefined();
     return promise.forget();
   }
 
   RefPtr<WorkerScopeSkipWaitingRunnable> runnable =
--- a/dom/workers/moz.build
+++ b/dom/workers/moz.build
@@ -66,17 +66,16 @@ UNIFIED_SOURCES += [
     'WorkerThread.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/caps',
     '/dom/base',
     '/dom/bindings',
     '/dom/system',
-    '/dom/workers/remoteworkers',
     '/js/xpconnect/loader',
     '/netwerk/base',
     '/xpcom/build',
     '/xpcom/threads',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     LOCAL_INCLUDES += [
--- a/dom/workers/remoteworkers/PRemoteWorker.ipdl
+++ b/dom/workers/remoteworkers/PRemoteWorker.ipdl
@@ -1,17 +1,15 @@
 /* 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 protocol PFetchEventOpProxy;
 
 include DOMTypes;
-include ServiceWorkerOpArgs;
 include RemoteWorkerTypes;
 
 namespace mozilla {
 namespace dom {
 
 struct RemoteWorkerSuspendOp
 {};
 
@@ -55,32 +53,23 @@ union RemoteWorkerOp {
 
 // This protocol is used to make a remote worker controllable from the parent
 // process. The parent process will receive operations from the
 // PRemoteWorkerController protocol.
 protocol PRemoteWorker
 {
   manager PBackground;
 
-  manages PFetchEventOpProxy;
-
 parent:
   async Created(bool aStatus);
 
   async Error(ErrorValue aValue);
 
   async Close();
 
-  async SetServiceWorkerSkipWaitingFlag() returns (bool aOk);
-
 child:
-  async PFetchEventOpProxy(ServiceWorkerFetchEventOpArgs aArgs);
-
   async __delete__();
 
   async ExecOp(RemoteWorkerOp op);
-
-  async ExecServiceWorkerOp(ServiceWorkerOpArgs aArgs)
-      returns (ServiceWorkerOpResult aResult);
 };
 
 } // namespace dom
 } // namespace mozilla
deleted file mode 100644
--- a/dom/workers/remoteworkers/PRemoteWorkerController.ipdl
+++ /dev/null
@@ -1,42 +0,0 @@
-/* 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 protocol PFetchEventOp;
-
-include RemoteWorkerTypes;
-include ServiceWorkerOpArgs;
-
-namespace mozilla {
-namespace dom {
-
-protocol PRemoteWorkerController {
-  manager PBackground;
-
-  manages PFetchEventOp;
-
- child:
-  async CreationFailed();
-
-  async CreationSucceeded();
-
-  async ErrorReceived(ErrorValue aError);
-
-  async Terminated();
-
-  async SetServiceWorkerSkipWaitingFlag() returns (bool aOk);
-
- parent:
-  async PFetchEventOp(ServiceWorkerFetchEventOpArgs aArgs);
-
-  async __delete__();
-
-  async Shutdown() returns (bool aOk);
-
-  async ExecServiceWorkerOp(ServiceWorkerOpArgs aArgs)
-      returns (ServiceWorkerOpResult aResult);
-};
-
-}  // namespace dom
-}  // namespace mozilla
--- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp
+++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp
@@ -1,103 +1,42 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "RemoteWorkerChild.h"
-
-#include <utility>
-
-#include "MainThreadUtils.h"
-#include "nsDebug.h"
-#include "nsError.h"
-#include "nsIConsoleReportCollector.h"
-#include "nsIInterfaceRequestor.h"
-#include "nsIPrincipal.h"
-#include "nsIPermissionManager.h"
-#include "nsNetUtil.h"
-#include "nsProxyRelease.h"
-#include "nsThreadUtils.h"
-#include "nsXULAppAPI.h"
-
 #include "RemoteWorkerService.h"
-#include "mozilla/Assertions.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/BasePrincipal.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Services.h"
-#include "mozilla/ScopeExit.h"
-#include "mozilla/Unused.h"
-#include "mozilla/dom/FetchEventOpProxyChild.h"
 #include "mozilla/dom/IndexedDatabaseManager.h"
 #include "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/RemoteWorkerTypes.h"
-#include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "mozilla/dom/ServiceWorkerInterceptController.h"
-#include "mozilla/dom/ServiceWorkerOp.h"
-#include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
 #include "mozilla/dom/ServiceWorkerUtils.h"
 #include "mozilla/dom/workerinternals/ScriptLoader.h"
 #include "mozilla/dom/WorkerError.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/WorkerRef.h"
 #include "mozilla/dom/WorkerRunnable.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/net/CookieSettings.h"
+#include "nsIConsoleReportCollector.h"
+#include "nsIPrincipal.h"
+#include "nsNetUtil.h"
+#include "nsProxyRelease.h"
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
 using workerinternals::ChannelFromScriptURLMainThread;
 
-class SelfHolder {
- public:
-  MOZ_IMPLICIT SelfHolder(RemoteWorkerChild* aSelf) : mSelf(aSelf) {
-    MOZ_ASSERT(mSelf);
-  }
-
-  SelfHolder(const SelfHolder&) = default;
-
-  SelfHolder& operator=(const SelfHolder&) = default;
-
-  SelfHolder(SelfHolder&&) = default;
-
-  SelfHolder& operator=(SelfHolder&&) = default;
-
-  ~SelfHolder() {
-    if (!mSelf) {
-      return;
-    }
-
-    nsCOMPtr<nsISerialEventTarget> target = mSelf->GetOwningEventTarget();
-    NS_ProxyRelease("SelfHolder::mSelf", target, mSelf.forget());
-  }
-
-  RemoteWorkerChild* get() const {
-    MOZ_ASSERT(mSelf);
-
-    return mSelf.get();
-  }
-
-  RemoteWorkerChild* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
-    return get();
-  }
-
-  bool operator!() { return !mSelf.get(); }
-
- private:
-  RefPtr<RemoteWorkerChild> mSelf;
-};
-
 namespace {
 
 class SharedWorkerInterfaceRequestor final : public nsIInterfaceRequestor {
  public:
   NS_DECL_ISUPPORTS
 
   SharedWorkerInterfaceRequestor() {
     // This check must match the code nsDocShell::Create.
@@ -131,20 +70,20 @@ class SharedWorkerInterfaceRequestor fin
 NS_IMPL_ADDREF(SharedWorkerInterfaceRequestor)
 NS_IMPL_RELEASE(SharedWorkerInterfaceRequestor)
 NS_IMPL_QUERY_INTERFACE(SharedWorkerInterfaceRequestor, nsIInterfaceRequestor)
 
 // Normal runnable because AddPortIdentifier() is going to exec JS code.
 class MessagePortIdentifierRunnable final : public WorkerRunnable {
  public:
   MessagePortIdentifierRunnable(WorkerPrivate* aWorkerPrivate,
-                                SelfHolder aActor,
+                                RemoteWorkerChild* aActor,
                                 const MessagePortIdentifier& aPortIdentifier)
       : WorkerRunnable(aWorkerPrivate),
-        mActor(std::move(aActor)),
+        mActor(aActor),
         mPortIdentifier(aPortIdentifier) {}
 
  private:
   virtual bool WorkerRun(JSContext* aCx,
                          WorkerPrivate* aWorkerPrivate) override {
     mActor->AddPortIdentifier(aCx, aWorkerPrivate, mPortIdentifier);
     return true;
   }
@@ -170,177 +109,94 @@ class MessagePortIdentifierRunnable fina
   }
 
   void PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
                bool aRunResult) override {
     // Silence bad assertions.
     return;
   }
 
-  SelfHolder mActor;
+  RefPtr<RemoteWorkerChild> mActor;
   MessagePortIdentifier mPortIdentifier;
 };
 
-class ReleaseWorkerRunnable final : public WorkerRunnable {
- public:
-  ReleaseWorkerRunnable(RefPtr<WorkerPrivate> aWorkerPrivate,
-                        already_AddRefed<WeakWorkerRef> aWeakRef)
-      : WorkerRunnable(aWorkerPrivate),
-        mWorkerPrivate(std::move(aWorkerPrivate)),
-        mWeakRef(aWeakRef) {}
-
- private:
-  bool WorkerRun(JSContext*, WorkerPrivate*) override {
-    mWeakRef = nullptr;
-    mWorkerPrivate = nullptr;
-
-    return true;
-  }
-
-  nsresult Cancel() override {
-    mWeakRef = nullptr;
-    mWorkerPrivate = nullptr;
-
-    return NS_OK;
-  }
-
-  RefPtr<WorkerPrivate> mWorkerPrivate;
-  RefPtr<WeakWorkerRef> mWeakRef;
-};
-
-}  // anonymous namespace
+}  // namespace
 
 class RemoteWorkerChild::InitializeWorkerRunnable final
     : public WorkerRunnable {
  public:
-  InitializeWorkerRunnable(RefPtr<WorkerPrivate> aWorkerPrivate,
-                           SelfHolder aActor)
-      : WorkerRunnable(aWorkerPrivate),
-        mWorkerPrivate(std::move(aWorkerPrivate)),
-        mActor(std::move(aActor)) {
-    MOZ_ASSERT(mWorkerPrivate);
-    MOZ_ASSERT(mActor);
-  }
+  InitializeWorkerRunnable(WorkerPrivate* aWorkerPrivate,
+                           RemoteWorkerChild* aActor)
+      : WorkerRunnable(aWorkerPrivate), mActor(aActor) {}
 
  private:
-  ~InitializeWorkerRunnable() { MaybeAbort(); }
-
-  bool WorkerRun(JSContext*, WorkerPrivate*) override {
-    mActor->InitializeOnWorker(mWorkerPrivate.forget());
+  virtual bool WorkerRun(JSContext* aCx,
+                         WorkerPrivate* aWorkerPrivate) override {
+    mActor->InitializeOnWorker(aWorkerPrivate);
     return true;
   }
 
   nsresult Cancel() override {
-    MaybeAbort();
-
+    mActor->CreationFailedOnAnyThread();
+    mActor->ShutdownOnWorker();
     return WorkerRunnable::Cancel();
   }
 
-  // Slowly running out of synonyms for cancel, abort, terminate, etc...
-  void MaybeAbort() {
-    if (!mWorkerPrivate) {
-      return;
-    }
-
-    nsCOMPtr<nsIEventTarget> target =
-        SystemGroup::EventTargetFor(TaskCategory::Other);
-    NS_ProxyRelease("InitializeWorkerRunnable::mWorkerPrivate", target,
-                    mWorkerPrivate.forget());
-
-    mActor->TransitionStateToTerminated();
-    mActor->CreationFailedOnAnyThread();
-    mActor->ShutdownOnWorker();
-  }
-
-  RefPtr<WorkerPrivate> mWorkerPrivate;
-  SelfHolder mActor;
+  RefPtr<RemoteWorkerChild> mActor;
 };
 
-RemoteWorkerChild::RemoteWorkerChild(const RemoteWorkerData& aData)
-    : mState(VariantType<Pending>(), "RemoteWorkerChild::mState"),
-      mIsServiceWorker(aData.serviceWorkerData().type() ==
-                       OptionalServiceWorkerData::TServiceWorkerData),
-      mOwningEventTarget(GetCurrentThreadSerialEventTarget()) {
+RemoteWorkerChild::RemoteWorkerChild()
+    : mIPCActive(true), mSharedData("RemoteWorkerChild::mSharedData") {
   MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
-  MOZ_ASSERT(mOwningEventTarget);
 }
 
+RemoteWorkerChild::SharedData::SharedData() : mWorkerState(ePending) {}
+
 RemoteWorkerChild::~RemoteWorkerChild() {
-#ifdef DEBUG
-  MOZ_ASSERT(mTerminationPromise.IsEmpty());
-  auto lock = mState.Lock();
-  MOZ_ASSERT(lock->is<Terminated>());
-#endif
-}
+  nsCOMPtr<nsIEventTarget> target =
+      SystemGroup::EventTargetFor(TaskCategory::Other);
 
-nsISerialEventTarget* RemoteWorkerChild::GetOwningEventTarget() const {
-  return mOwningEventTarget;
+  const auto lock = mSharedData.Lock();
+  NS_ProxyRelease("RemoteWorkerChild::mWorkerPrivate", target,
+                  lock->mWorkerPrivate.forget());
 }
 
-void RemoteWorkerChild::ActorDestroy(ActorDestroyReason) {
-  Unused << NS_WARN_IF(!mTerminationPromise.IsEmpty());
-  mTerminationPromise.RejectIfExists(NS_ERROR_DOM_ABORT_ERR, __func__);
-
-  MOZ_ACCESS_THREAD_BOUND(mLauncherData, launcherData);
-  launcherData->mIPCActive = false;
-
-  auto lock = mState.Lock();
-
-  Unused << NS_WARN_IF(!lock->is<Terminated>());
-
-  if (NS_WARN_IF(lock->is<Running>())) {
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-        __func__,
-        [workerPrivate = std::move(lock->as<Running>().mWorkerPrivate),
-         workerRef = std::move(lock->as<Running>().mWorkerRef)]() mutable {
-          RefPtr<ReleaseWorkerRunnable> r =
-              new ReleaseWorkerRunnable(workerPrivate, workerRef.forget());
-
-          Unused << NS_WARN_IF(!r->Dispatch());
-
-          workerPrivate->Cancel();
-        });
-
-    MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
-  }
-
-  *lock = VariantType<Terminated>();
+void RemoteWorkerChild::ActorDestroy(ActorDestroyReason aWhy) {
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
+  mIPCActive = false;
+  data->mPendingOps.Clear();
 }
 
 void RemoteWorkerChild::ExecWorker(const RemoteWorkerData& aData) {
-#ifdef DEBUG
-  MOZ_ASSERT(GetOwningEventTarget()->IsOnCurrentThread());
-  MOZ_ACCESS_THREAD_BOUND(mLauncherData, launcherData);
-  MOZ_ASSERT(launcherData->mIPCActive);
-#endif
+  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
+  MOZ_ASSERT(mIPCActive);
 
-  SelfHolder self = this;
-
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-      __func__, [self = std::move(self), data = aData]() mutable {
-        nsresult rv = self->ExecWorkerOnMainThread(std::move(data));
-
+  RefPtr<RemoteWorkerChild> self = this;
+  nsCOMPtr<nsIRunnable> r =
+      NS_NewRunnableFunction("RemoteWorkerChild::ExecWorker", [self, aData]() {
+        nsresult rv = self->ExecWorkerOnMainThread(aData);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           self->CreationFailedOnAnyThread();
         }
       });
 
-  MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
+  nsCOMPtr<nsIEventTarget> target =
+      SystemGroup::EventTargetFor(TaskCategory::Other);
+  target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
-nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) {
+nsresult RemoteWorkerChild::ExecWorkerOnMainThread(
+    const RemoteWorkerData& aData) {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Ensure that the IndexedDatabaseManager is initialized
   Unused << NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate());
 
   nsresult rv = NS_OK;
 
-  auto scopeExit = MakeScopeExit([&] { TransitionStateToTerminated(); });
-
   nsCOMPtr<nsIPrincipal> principal =
       PrincipalInfoToPrincipal(aData.principalInfo(), &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsCOMPtr<nsIPrincipal> loadingPrincipal =
       PrincipalInfoToPrincipal(aData.loadingPrincipalInfo(), &rv);
@@ -403,239 +259,124 @@ nsresult RemoteWorkerChild::ExecWorkerOn
   }
 
   rv = info.SetPrincipalsAndCSPOnMainThread(
       info.mPrincipal, info.mStoragePrincipal, info.mLoadGroup, info.mCSP);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  if (mIsServiceWorker) {
-    ServiceWorkerData& data = aData.serviceWorkerData().get_ServiceWorkerData();
-
-    nsCOMPtr<nsIPermissionManager> permissionManager =
-        services::GetPermissionManager();
-
-    for (auto& keyAndPermissions : data.permissionsByKey()) {
-      permissionManager->SetPermissionsWithKey(keyAndPermissions.key(),
-                                               keyAndPermissions.permissions());
-    }
-
-    info.mServiceWorkerCacheName = data.cacheName();
-    info.mServiceWorkerDescriptor.emplace(data.descriptor());
-    info.mServiceWorkerRegistrationDescriptor.emplace(
-        data.registrationDescriptor());
-    info.mLoadFlags = static_cast<nsLoadFlags>(data.loadFlags());
-  } else {
-    // Top level workers' main script use the document charset for the script
-    // uri encoding.
-    rv = ChannelFromScriptURLMainThread(
-        info.mLoadingPrincipal, nullptr /* parent document */, info.mLoadGroup,
-        info.mResolvedScriptURI, clientInfo,
-        nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER, info.mCookieSettings,
-        info.mReferrerInfo, getter_AddRefs(info.mChannel));
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
+  // Top level workers' main script use the document charset for the script
+  // uri encoding.
+  rv = ChannelFromScriptURLMainThread(
+      info.mLoadingPrincipal, nullptr /* parent document */, info.mLoadGroup,
+      info.mResolvedScriptURI, clientInfo,
+      aData.isSharedWorker() ? nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER
+                             : nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER,
+      info.mCookieSettings, info.mReferrerInfo, getter_AddRefs(info.mChannel));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
   }
 
   AutoJSAPI jsapi;
   jsapi.Init();
 
   ErrorResult error;
-  RefPtr<WorkerPrivate> workerPrivate = WorkerPrivate::Constructor(
+  const auto lock = mSharedData.Lock();
+  lock->mWorkerPrivate = WorkerPrivate::Constructor(
       jsapi.cx(), aData.originalScriptURL(), false,
-      mIsServiceWorker ? WorkerTypeService : WorkerTypeShared, aData.name(),
-      VoidCString(), &info, error);
-
+      aData.isSharedWorker() ? WorkerTypeShared : WorkerTypeService,
+      aData.name(), VoidCString(), &info, error);
   if (NS_WARN_IF(error.Failed())) {
-    MOZ_ASSERT(!workerPrivate);
-
-    rv = error.StealNSResult();
-    return rv;
-  }
-
-  if (mIsServiceWorker) {
-    RefPtr<RemoteWorkerChild> self = this;
-    workerPrivate->SetRemoteWorkerControllerWeakRef(
-        ThreadSafeWeakPtr<RemoteWorkerChild>(self));
-  } else {
-    workerPrivate->SetRemoteWorkerController(this);
+    return error.StealNSResult();
   }
 
   RefPtr<InitializeWorkerRunnable> runnable =
-      new InitializeWorkerRunnable(std::move(workerPrivate), SelfHolder(this));
-
+      new InitializeWorkerRunnable(lock->mWorkerPrivate, this);
   if (NS_WARN_IF(!runnable->Dispatch())) {
-    rv = NS_ERROR_FAILURE;
-    return rv;
+    return NS_ERROR_FAILURE;
   }
 
-  scopeExit.release();
-
+  lock->mWorkerPrivate->SetRemoteWorkerController(this);
   return NS_OK;
 }
 
-void RemoteWorkerChild::InitializeOnWorker(
-    already_AddRefed<WorkerPrivate> aWorkerPrivate) {
-  {
-    auto lock = mState.Lock();
-
-    if (lock->is<PendingTerminated>()) {
-      nsCOMPtr<nsIEventTarget> target =
-          SystemGroup::EventTargetFor(TaskCategory::Other);
-      NS_ProxyRelease(__func__, target, std::move(aWorkerPrivate));
-
-      TransitionStateToTerminated(lock.ref());
-      ShutdownOnWorker();
-      return;
-    }
-  }
-
-  RefPtr<WorkerPrivate> workerPrivate = aWorkerPrivate;
-  MOZ_ASSERT(workerPrivate);
-  workerPrivate->AssertIsOnWorkerThread();
+void RemoteWorkerChild::InitializeOnWorker(WorkerPrivate* aWorkerPrivate) {
+  MOZ_ASSERT(aWorkerPrivate);
+  aWorkerPrivate->AssertIsOnWorkerThread();
 
   RefPtr<RemoteWorkerChild> self = this;
-  ThreadSafeWeakPtr<RemoteWorkerChild> selfWeakRef(self);
-
-  auto scopeExit = MakeScopeExit([&] {
-    MOZ_ASSERT(self);
-
-    NS_ProxyRelease(__func__, mOwningEventTarget, self.forget());
-  });
-
-  RefPtr<WeakWorkerRef> workerRef = WeakWorkerRef::Create(
-      workerPrivate, [selfWeakRef = std::move(selfWeakRef)]() mutable {
-        RefPtr<RemoteWorkerChild> self(selfWeakRef);
+  {
+    const auto lock = mSharedData.Lock();
+    mWorkerRef = WeakWorkerRef::Create(lock->mWorkerPrivate,
+                                       [self]() { self->ShutdownOnWorker(); });
+  }
 
-        if (NS_WARN_IF(!self)) {
-          return;
-        }
-
-        self->TransitionStateToTerminated();
-        self->ShutdownOnWorker();
-
-        nsCOMPtr<nsISerialEventTarget> target = self->GetOwningEventTarget();
-        NS_ProxyRelease(__func__, target, self.forget());
-      });
-
-  if (NS_WARN_IF(!workerRef)) {
-    TransitionStateToTerminated();
+  if (NS_WARN_IF(!mWorkerRef)) {
     CreationFailedOnAnyThread();
     ShutdownOnWorker();
-
     return;
   }
 
-  TransitionStateToRunning(workerPrivate.forget(), workerRef.forget());
   CreationSucceededOnAnyThread();
 }
 
 void RemoteWorkerChild::ShutdownOnWorker() {
-  RefPtr<RemoteWorkerChild> self = this;
-
-  nsCOMPtr<nsIRunnable> r =
-      NS_NewRunnableFunction(__func__, [self = std::move(self)] {
-        MOZ_ACCESS_THREAD_BOUND(self->mLauncherData, launcherData);
+  const auto lock = mSharedData.Lock();
+  MOZ_ASSERT(lock->mWorkerPrivate);
+  lock->mWorkerPrivate->AssertIsOnWorkerThread();
 
-        if (!launcherData->mIPCActive) {
-          return;
-        }
+  // This will release the worker.
+  mWorkerRef = nullptr;
 
-        launcherData->mIPCActive = false;
-        Unused << self->SendClose();
-      });
+  nsCOMPtr<nsIEventTarget> target =
+      SystemGroup::EventTargetFor(TaskCategory::Other);
 
-  GetOwningEventTarget()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-}
-
-RefPtr<GenericNonExclusivePromise> RemoteWorkerChild::GetTerminationPromise() {
-  MOZ_ASSERT(GetOwningEventTarget()->IsOnCurrentThread());
+  NS_ProxyRelease("RemoteWorkerChild::mWorkerPrivate", target,
+                  lock->mWorkerPrivate.forget());
 
-  return mTerminationPromise.Ensure(__func__);
-}
+  RefPtr<RemoteWorkerChild> self = this;
+  nsCOMPtr<nsIRunnable> r =
+      NS_NewRunnableFunction("RemoteWorkerChild::ShutdownOnWorker",
+                             [self]() { self->WorkerTerminated(); });
 
-void RemoteWorkerChild::CreationSucceededOnAnyThread() {
-  CreationSucceededOrFailedOnAnyThread(true);
-}
-
-void RemoteWorkerChild::CreationFailedOnAnyThread() {
-  CreationSucceededOrFailedOnAnyThread(false);
+  RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
-void RemoteWorkerChild::CreationSucceededOrFailedOnAnyThread(
-    bool aDidCreationSucceed) {
-#ifdef DEBUG
-  auto lock = mState.Lock();
-  MOZ_ASSERT_IF(aDidCreationSucceed, lock->is<Running>());
-  MOZ_ASSERT_IF(!aDidCreationSucceed, lock->is<Terminated>());
-#endif
-
-  RefPtr<RemoteWorkerChild> self = this;
-
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-      __func__,
-      [self = std::move(self), didCreationSucceed = aDidCreationSucceed] {
-        MOZ_ACCESS_THREAD_BOUND(self->mLauncherData, launcherData);
+void RemoteWorkerChild::WorkerTerminated() {
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
 
-        if (!launcherData->mIPCActive) {
-          return;
-        }
-
-        Unused << self->SendCreated(didCreationSucceed);
-      });
+  {
+    const auto lock = mSharedData.Lock();
+    lock->mWorkerState = eTerminated;
+  }
+  data->mPendingOps.Clear();
 
-  Unused << GetOwningEventTarget()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-}
-
-void RemoteWorkerChild::CloseWorkerOnMainThread(State& aState) {
-  AssertIsOnMainThread();
-  MOZ_ASSERT(!aState.is<PendingTerminated>());
-
-  if (aState.is<Pending>()) {
-    TransitionStateToPendingTerminated(aState);
+  if (!mIPCActive) {
     return;
   }
 
-  // The holder will be notified by this.
-  if (aState.is<Running>()) {
-    aState.as<Running>().mWorkerPrivate->Cancel();
-  }
-}
-
-/**
- * Error reporting method
- */
-void RemoteWorkerChild::ErrorPropagation(const ErrorValue& aValue) {
-  MOZ_ASSERT(GetOwningEventTarget()->IsOnCurrentThread());
-
-  MOZ_ACCESS_THREAD_BOUND(mLauncherData, launcherData);
-
-  if (!launcherData->mIPCActive) {
-    return;
-  }
-
-  Unused << SendError(aValue);
+  Unused << SendClose();
+  mIPCActive = false;
 }
 
 void RemoteWorkerChild::ErrorPropagationDispatch(nsresult aError) {
   MOZ_ASSERT(NS_FAILED(aError));
 
   RefPtr<RemoteWorkerChild> self = this;
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
       "RemoteWorkerChild::ErrorPropagationDispatch",
-      [self = std::move(self), aError]() { self->ErrorPropagation(aError); });
+      [self, aError]() { self->ErrorPropagation(aError); });
 
-  GetOwningEventTarget()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
+  RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
 void RemoteWorkerChild::ErrorPropagationOnMainThread(
     const WorkerErrorReport* aReport, bool aIsErrorEvent) {
-  AssertIsOnMainThread();
+  MOZ_ASSERT(NS_IsMainThread());
 
   ErrorValue value;
   if (aIsErrorEvent) {
     nsTArray<ErrorDataNote> notes;
     for (size_t i = 0, len = aReport->mNotes.Length(); i < len; i++) {
       const WorkerErrorNote& note = aReport->mNotes.ElementAt(i);
       notes.AppendElement(ErrorDataNote(note.mLineNumber, note.mColumnNumber,
                                         note.mMessage, note.mFilename));
@@ -647,24 +388,57 @@ void RemoteWorkerChild::ErrorPropagation
     value = data;
   } else {
     value = void_t();
   }
 
   RefPtr<RemoteWorkerChild> self = this;
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
       "RemoteWorkerChild::ErrorPropagationOnMainThread",
-      [self = std::move(self), value]() { self->ErrorPropagation(value); });
+      [self, value]() { self->ErrorPropagation(value); });
+
+  RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
+}
+
+void RemoteWorkerChild::ErrorPropagation(const ErrorValue& aValue) {
+  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
+
+  if (!mIPCActive) {
+    return;
+  }
+
+  Unused << SendError(aValue);
+}
 
-  GetOwningEventTarget()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
+void RemoteWorkerChild::CloseWorkerOnMainThread() {
+  MOZ_ASSERT(NS_IsMainThread());
+  const auto lock = mSharedData.Lock();
+
+  if (lock->mWorkerState == ePending) {
+    lock->mWorkerState = ePendingTerminated;
+    // Already released.
+    return;
+  }
+
+  // The holder will be notified by this.
+  if (lock->mWorkerState == eRunning) {
+    // FIXME: mWorkerState transition and each state's associated data should
+    // be improved/fixed in bug 1231213. `!lock->mWorkerPrivate` implies that
+    // the worker state is effectively `eTerminated.`
+    if (!lock->mWorkerPrivate) {
+      return;
+    }
+
+    lock->mWorkerPrivate->Cancel();
+  }
 }
 
 void RemoteWorkerChild::FlushReportsOnMainThread(
     nsIConsoleReportCollector* aReporter) {
-  AssertIsOnMainThread();
+  MOZ_ASSERT(NS_IsMainThread());
 
   bool reportErrorToBrowserConsole = true;
 
   // Flush the reports.
   for (uint32_t i = 0, len = mWindowIDs.Length(); i < len; ++i) {
     aReporter->FlushReportsToConsole(
         mWindowIDs[i], nsIConsoleReportCollector::ReportAction::Save);
     reportErrorToBrowserConsole = false;
@@ -674,336 +448,199 @@ void RemoteWorkerChild::FlushReportsOnMa
   if (reportErrorToBrowserConsole) {
     aReporter->FlushReportsToConsole(0);
     return;
   }
 
   aReporter->ClearConsoleReports();
 }
 
-/**
- * Worker state transition methods
- */
-RemoteWorkerChild::Running::~Running() {
-  if (!mWorkerPrivate) {
+IPCResult RemoteWorkerChild::RecvExecOp(const RemoteWorkerOp& aOp) {
+  const auto lock = mSharedData.Lock();
+  return ExecuteOperation(aOp, lock);
+}
+
+template <typename T>
+IPCResult RemoteWorkerChild::ExecuteOperation(const RemoteWorkerOp& aOp,
+                                              const T& aLock) {
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
+
+  if (!mIPCActive) {
+    return IPC_OK();
+  }
+
+  // The worker is not ready yet.
+  if (aLock->mWorkerState == ePending) {
+    data->mPendingOps.AppendElement(aOp);
+    return IPC_OK();
+  }
+
+  if (aLock->mWorkerState == eTerminated ||
+      aLock->mWorkerState == ePendingTerminated) {
+    // No op.
+    return IPC_OK();
+  }
+
+  MOZ_ASSERT(aLock->mWorkerState == eRunning);
+
+  // Main-thread operations
+  if (aOp.type() == RemoteWorkerOp::TRemoteWorkerSuspendOp ||
+      aOp.type() == RemoteWorkerOp::TRemoteWorkerResumeOp ||
+      aOp.type() == RemoteWorkerOp::TRemoteWorkerFreezeOp ||
+      aOp.type() == RemoteWorkerOp::TRemoteWorkerThawOp ||
+      aOp.type() == RemoteWorkerOp::TRemoteWorkerTerminateOp ||
+      aOp.type() == RemoteWorkerOp::TRemoteWorkerAddWindowIDOp ||
+      aOp.type() == RemoteWorkerOp::TRemoteWorkerRemoveWindowIDOp) {
+    RefPtr<RemoteWorkerChild> self = this;
+    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
+        "RemoteWorkerChild::RecvExecOp",
+        [self, aOp]() { self->RecvExecOpOnMainThread(aOp); });
+
+    nsCOMPtr<nsIEventTarget> target =
+        SystemGroup::EventTargetFor(TaskCategory::Other);
+    target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
+    return IPC_OK();
+  }
+
+  if (aOp.type() == RemoteWorkerOp::TRemoteWorkerPortIdentifierOp) {
+    const RemoteWorkerPortIdentifierOp& op =
+        aOp.get_RemoteWorkerPortIdentifierOp();
+    RefPtr<MessagePortIdentifierRunnable> runnable =
+        new MessagePortIdentifierRunnable(aLock->mWorkerPrivate, this,
+                                          op.portIdentifier());
+    if (NS_WARN_IF(!runnable->Dispatch())) {
+      ErrorPropagation(NS_ERROR_FAILURE);
+    }
+    return IPC_OK();
+  }
+
+  MOZ_CRASH("Unknown operation.");
+
+  return IPC_OK();
+}
+
+void RemoteWorkerChild::RecvExecOpOnMainThread(const RemoteWorkerOp& aOp) {
+  MOZ_ASSERT(NS_IsMainThread());
+
+  {
+    const auto lock = mSharedData.Lock();
+
+    if (aOp.type() == RemoteWorkerOp::TRemoteWorkerSuspendOp) {
+      if (lock->mWorkerPrivate) {
+        lock->mWorkerPrivate->ParentWindowPaused();
+      }
+      return;
+    }
+
+    if (aOp.type() == RemoteWorkerOp::TRemoteWorkerResumeOp) {
+      if (lock->mWorkerPrivate) {
+        lock->mWorkerPrivate->ParentWindowResumed();
+      }
+      return;
+    }
+
+    if (aOp.type() == RemoteWorkerOp::TRemoteWorkerFreezeOp) {
+      if (lock->mWorkerPrivate) {
+        lock->mWorkerPrivate->Freeze(nullptr);
+      }
+      return;
+    }
+
+    if (aOp.type() == RemoteWorkerOp::TRemoteWorkerThawOp) {
+      if (lock->mWorkerPrivate) {
+        lock->mWorkerPrivate->Thaw(nullptr);
+      }
+      return;
+    }
+  }
+
+  if (aOp.type() == RemoteWorkerOp::TRemoteWorkerTerminateOp) {
+    CloseWorkerOnMainThread();
     return;
   }
 
-  nsCOMPtr<nsIEventTarget> target =
-      SystemGroup::EventTargetFor(TaskCategory::Other);
-  NS_ProxyRelease("RemoteWorkerChild::Running::mWorkerPrivate", target,
-                  mWorkerPrivate.forget());
-}
-
-void RemoteWorkerChild::TransitionStateToPendingTerminated(State& aState) {
-  MOZ_ASSERT(aState.is<Pending>());
-
-  CancelAllPendingOps(aState);
-
-  aState = VariantType<PendingTerminated>();
-}
-
-void RemoteWorkerChild::TransitionStateToRunning(
-    already_AddRefed<WorkerPrivate> aWorkerPrivate,
-    already_AddRefed<WeakWorkerRef> aWorkerRef) {
-  RefPtr<WorkerPrivate> workerPrivate = aWorkerPrivate;
-  MOZ_ASSERT(workerPrivate);
-
-  RefPtr<WeakWorkerRef> workerRef = aWorkerRef;
-  MOZ_ASSERT(workerRef);
-
-  auto lock = mState.Lock();
-
-  MOZ_ASSERT(lock->is<Pending>());
-
-  auto pendingOps = std::move(lock->as<Pending>().mPendingOps);
-
-  /**
-   * I'd initialize the WorkerPrivate and WeakWorkerRef in the constructor,
-   * but mozilla::Variant attempts to call the thread-unsafe `AddRef()` on
-   * WorkerPrivate.
-   */
-  *lock = VariantType<Running>();
-  lock->as<Running>().mWorkerPrivate = std::move(workerPrivate);
-  lock->as<Running>().mWorkerRef = std::move(workerRef);
-
-  SelfHolder self = this;
-
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-      __func__, [pendingOps = std::move(pendingOps), self = std::move(self)]() {
-        for (auto& op : pendingOps) {
-          auto lock = self->mState.Lock();
-
-          DebugOnly<bool> started = op->MaybeStart(self.get(), lock.ref());
-          MOZ_ASSERT(started);
-        }
-      });
-
-  MOZ_ALWAYS_SUCCEEDS(
-      mOwningEventTarget->Dispatch(r.forget(), NS_DISPATCH_NORMAL));
-}
-
-void RemoteWorkerChild::TransitionStateToTerminated() {
-  auto lock = mState.Lock();
-
-  TransitionStateToTerminated(lock.ref());
-}
-
-void RemoteWorkerChild::TransitionStateToTerminated(State& aState) {
-  if (aState.is<Pending>()) {
-    CancelAllPendingOps(aState);
+  if (aOp.type() == RemoteWorkerOp::TRemoteWorkerAddWindowIDOp) {
+    mWindowIDs.AppendElement(aOp.get_RemoteWorkerAddWindowIDOp().windowID());
+    return;
   }
 
-  mTerminationPromise.ResolveIfExists(true, __func__);
-
-  aState = VariantType<Terminated>();
-}
-
-/**
- * Operation execution classes/methods
- */
-class RemoteWorkerChild::SharedWorkerOp : public RemoteWorkerChild::Op {
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerOp, override)
-
-  explicit SharedWorkerOp(RemoteWorkerOp&& aOp) : mOp(std::move(aOp)) {}
-
-  bool MaybeStart(RemoteWorkerChild* aOwner,
-                  RemoteWorkerChild::State& aState) override {
-    MOZ_ASSERT(!mStarted);
-    MOZ_ASSERT(aOwner);
-
-    MOZ_ACCESS_THREAD_BOUND(aOwner->mLauncherData, launcherData);
-
-    if (NS_WARN_IF(!launcherData->mIPCActive)) {
-      Unused << NS_WARN_IF(!aState.is<Terminated>());
-
-#ifdef DEBUG
-      mStarted = true;
-#endif
-
-      return true;
-    }
-
-    if (aState.is<Pending>() && !IsTerminationOp()) {
-      return false;
-    }
-
-    if (aState.is<PendingTerminated>() || aState.is<Terminated>()) {
-#ifdef DEBUG
-      mStarted = true;
-#endif
-
-      return true;
-    }
-
-    MOZ_ASSERT(aState.is<Running>() || IsTerminationOp());
-
-    RefPtr<SharedWorkerOp> self = this;
-    SelfHolder owner = aOwner;
-
-    nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-        __func__, [self = std::move(self), owner = std::move(owner)]() mutable {
-          {
-            auto lock = owner->mState.Lock();
-
-            if (NS_WARN_IF(lock->is<Terminated>())) {
-              self->Cancel();
-              return;
-            }
-          }
-
-          self->Exec(owner);
-        });
-
-    MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
-
-#ifdef DEBUG
-    mStarted = true;
-#endif
-
-    return true;
+  if (aOp.type() == RemoteWorkerOp::TRemoteWorkerRemoveWindowIDOp) {
+    mWindowIDs.RemoveElement(aOp.get_RemoteWorkerRemoveWindowIDOp().windowID());
+    return;
   }
 
-  void Cancel() override {
-    MOZ_ASSERT(!mStarted);
-
-#ifdef DEBUG
-    mStarted = true;
-#endif
-  }
-
- private:
-  ~SharedWorkerOp() { MOZ_ASSERT(mStarted); }
-
-  bool IsTerminationOp() const {
-    return mOp.type() == RemoteWorkerOp::TRemoteWorkerTerminateOp;
-  }
-
-  void Exec(SelfHolder& aOwner) {
-    using Running = RemoteWorkerChild::Running;
-
-    AssertIsOnMainThread();
-
-    auto lock = aOwner->mState.Lock();
-
-    MOZ_ASSERT(lock->is<Running>() || IsTerminationOp());
-
-    if (IsTerminationOp()) {
-      aOwner->CloseWorkerOnMainThread(lock.ref());
-      return;
-    }
-
-    RefPtr<WorkerPrivate> workerPrivate = lock->as<Running>().mWorkerPrivate;
-
-    MOZ_ASSERT(workerPrivate);
-
-    if (mOp.type() == RemoteWorkerOp::TRemoteWorkerSuspendOp) {
-      workerPrivate->ParentWindowPaused();
-    } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerResumeOp) {
-      workerPrivate->ParentWindowResumed();
-    } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerFreezeOp) {
-      workerPrivate->Freeze(nullptr);
-    } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerThawOp) {
-      workerPrivate->Thaw(nullptr);
-    } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerPortIdentifierOp) {
-      RefPtr<MessagePortIdentifierRunnable> r =
-          new MessagePortIdentifierRunnable(
-              workerPrivate, aOwner,
-              mOp.get_RemoteWorkerPortIdentifierOp().portIdentifier());
-
-      if (NS_WARN_IF(!r->Dispatch())) {
-        aOwner->ErrorPropagation(NS_ERROR_FAILURE);
-      }
-    } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerAddWindowIDOp) {
-      aOwner->mWindowIDs.AppendElement(
-          mOp.get_RemoteWorkerAddWindowIDOp().windowID());
-    } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerRemoveWindowIDOp) {
-      aOwner->mWindowIDs.RemoveElement(
-          mOp.get_RemoteWorkerRemoveWindowIDOp().windowID());
-    } else {
-      MOZ_CRASH("Unknown RemoteWorkerOp type!");
-    }
-  }
-
-  RemoteWorkerOp mOp;
-
-#ifdef DEBUG
-  bool mStarted = false;
-#endif
-};
+  MOZ_CRASH("No other operations should be scheduled on main-thread.");
+}
 
 void RemoteWorkerChild::AddPortIdentifier(
     JSContext* aCx, WorkerPrivate* aWorkerPrivate,
     const MessagePortIdentifier& aPortIdentifier) {
   if (NS_WARN_IF(!aWorkerPrivate->ConnectMessagePort(aCx, aPortIdentifier))) {
     ErrorPropagationDispatch(NS_ERROR_FAILURE);
   }
 }
 
-void RemoteWorkerChild::CancelAllPendingOps(State& aState) {
-  MOZ_ASSERT(aState.is<Pending>());
-
-  auto pendingOps = std::move(aState.as<Pending>().mPendingOps);
-
-  for (auto& op : pendingOps) {
-    op->Cancel();
-  }
-}
-
-void RemoteWorkerChild::MaybeStartOp(RefPtr<Op>&& aOp) {
-  MOZ_ASSERT(aOp);
-
-  auto lock = mState.Lock();
+void RemoteWorkerChild::CreationSucceededOnAnyThread() {
+  RefPtr<RemoteWorkerChild> self = this;
+  nsCOMPtr<nsIRunnable> r =
+      NS_NewRunnableFunction("RemoteWorkerChild::CreationSucceededOnAnyThread",
+                             [self]() { self->CreationSucceeded(); });
 
-  if (!aOp->MaybeStart(this, lock.ref())) {
-    lock->as<Pending>().mPendingOps.AppendElement(std::move(aOp));
-  }
-}
-
-IPCResult RemoteWorkerChild::RecvExecOp(RemoteWorkerOp&& aOp) {
-  MOZ_ASSERT(!mIsServiceWorker);
-
-  MaybeStartOp(new SharedWorkerOp(std::move(aOp)));
-
-  return IPC_OK();
-}
-
-IPCResult RemoteWorkerChild::RecvExecServiceWorkerOp(
-    ServiceWorkerOpArgs&& aArgs, ExecServiceWorkerOpResolver&& aResolve) {
-  MOZ_ASSERT(mIsServiceWorker);
-  MOZ_ASSERT(
-      aArgs.type() != ServiceWorkerOpArgs::TServiceWorkerFetchEventOpArgs,
-      "FetchEvent operations should be sent via PFetchEventOp(Proxy) actors!");
-
-  MaybeStartOp(ServiceWorkerOp::Create(aArgs, std::move(aResolve)));
-
-  return IPC_OK();
+  RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
-RefPtr<GenericPromise>
-RemoteWorkerChild::MaybeSendSetServiceWorkerSkipWaitingFlag() {
-  RefPtr<GenericPromise::Private> promise =
-      new GenericPromise::Private(__func__);
-
-  RefPtr<RemoteWorkerChild> self = this;
+void RemoteWorkerChild::CreationSucceeded() {
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
 
-  nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(__func__, [self = std::move(
-                                                                  self),
-                                                              promise] {
-    MOZ_ACCESS_THREAD_BOUND(self->mLauncherData, launcherData);
-
-    if (!launcherData->mIPCActive) {
-      promise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__);
-      return;
-    }
+  // The worker is created but we need to terminate it already.
+  const auto lock = mSharedData.Lock();
+  if (lock->mWorkerState == ePendingTerminated) {
+    RefPtr<RemoteWorkerChild> self = this;
+    nsCOMPtr<nsIRunnable> r =
+        NS_NewRunnableFunction("RemoteWorkerChild::CreationSucceeded",
+                               [self]() { self->CloseWorkerOnMainThread(); });
 
-    self->SendSetServiceWorkerSkipWaitingFlag()->Then(
-        GetCurrentThreadSerialEventTarget(), __func__,
-        [promise](
-            const SetServiceWorkerSkipWaitingFlagPromise::ResolveOrRejectValue&
-                aResult) {
-          if (NS_WARN_IF(aResult.IsReject())) {
-            promise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__);
-            return;
-          }
+    nsCOMPtr<nsIEventTarget> target =
+        SystemGroup::EventTargetFor(TaskCategory::Other);
+    target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
+    return;
+  }
+
+  lock->mWorkerState = eRunning;
 
-          promise->Resolve(aResult.ResolveValue(), __func__);
-        });
-  });
+  if (!mIPCActive) {
+    return;
+  }
 
-  GetOwningEventTarget()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
+  for (const RemoteWorkerOp& op : data->mPendingOps) {
+    ExecuteOperation(op, lock);
+  }
 
-  return promise;
+  data->mPendingOps.Clear();
+
+  Unused << SendCreated(true);
 }
 
-/**
- * PFetchEventOpProxy methods
- */
-PFetchEventOpProxyChild* RemoteWorkerChild::AllocPFetchEventOpProxyChild(
-    const ServiceWorkerFetchEventOpArgs& aArgs) {
-  RefPtr<FetchEventOpProxyChild> actor = new FetchEventOpProxyChild();
+void RemoteWorkerChild::CreationFailedOnAnyThread() {
+  RefPtr<RemoteWorkerChild> self = this;
+  nsCOMPtr<nsIRunnable> r =
+      NS_NewRunnableFunction("RemoteWorkerChild::CreationFailedOnAnyThread",
+                             [self]() { self->CreationFailed(); });
 
-  return actor.forget().take();
+  RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
-IPCResult RemoteWorkerChild::RecvPFetchEventOpProxyConstructor(
-    PFetchEventOpProxyChild* aActor,
-    const ServiceWorkerFetchEventOpArgs& aArgs) {
-  MOZ_ASSERT(aActor);
-
-  (static_cast<FetchEventOpProxyChild*>(aActor))->Initialize(aArgs);
+void RemoteWorkerChild::CreationFailed() {
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
 
-  return IPC_OK();
-}
+  const auto lock = mSharedData.Lock();
+  lock->mWorkerState = eTerminated;
+  data->mPendingOps.Clear();
 
-bool RemoteWorkerChild::DeallocPFetchEventOpProxyChild(
-    PFetchEventOpProxyChild* aActor) {
-  MOZ_ASSERT(aActor);
+  if (!mIPCActive) {
+    return;
+  }
 
-  RefPtr<FetchEventOpProxyChild> actor =
-      dont_AddRef(static_cast<FetchEventOpProxyChild*>(aActor));
-
-  return true;
+  Unused << SendCreated(false);
 }
 
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/workers/remoteworkers/RemoteWorkerChild.h
+++ b/dom/workers/remoteworkers/RemoteWorkerChild.h
@@ -2,167 +2,124 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_dom_RemoteWorkerChild_h
 #define mozilla_dom_RemoteWorkerChild_h
 
-#include "nsCOMPtr.h"
-#include "nsISupportsImpl.h"
-#include "nsTArray.h"
-
+#include "mozilla/dom/PRemoteWorkerChild.h"
 #include "mozilla/DataMutex.h"
-#include "mozilla/MozPromise.h"
-#include "mozilla/RefPtr.h"
 #include "mozilla/ThreadBound.h"
-#include "mozilla/ThreadSafeWeakPtr.h"
-#include "mozilla/dom/PRemoteWorkerChild.h"
-#include "mozilla/dom/ServiceWorkerOpArgs.h"
+#include "mozilla/UniquePtr.h"
+#include "nsISupportsImpl.h"
 
-class nsISerialEventTarget;
 class nsIConsoleReportCollector;
 
 namespace mozilla {
 namespace dom {
 
-class ErrorValue;
-class FetchEventOpProxyChild;
 class RemoteWorkerData;
-class ServiceWorkerOp;
 class WeakWorkerRef;
 class WorkerErrorReport;
 class WorkerPrivate;
+class OptionalMessagePortIdentifier;
 
-class RemoteWorkerChild final
-    : public SupportsThreadSafeWeakPtr<RemoteWorkerChild>,
-      public PRemoteWorkerChild {
-  friend class FetchEventOpProxyChild;
+class RemoteWorkerChild final : public PRemoteWorkerChild {
   friend class PRemoteWorkerChild;
-  friend class ServiceWorkerOp;
 
  public:
-  MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(RemoteWorkerChild)
-
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(RemoteWorkerChild)
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteWorkerChild)
 
-  explicit RemoteWorkerChild(const RemoteWorkerData& aData);
-
-  ~RemoteWorkerChild();
-
-  nsISerialEventTarget* GetOwningEventTarget() const;
+  RemoteWorkerChild();
 
   void ExecWorker(const RemoteWorkerData& aData);
 
+  void InitializeOnWorker(WorkerPrivate* aWorkerPrivate);
+
+  void ShutdownOnWorker();
+
+  void AddPortIdentifier(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
+                         const MessagePortIdentifier& aPortIdentifier);
+
   void ErrorPropagationOnMainThread(const WorkerErrorReport* aReport,
                                     bool aIsErrorEvent);
 
-  void FlushReportsOnMainThread(nsIConsoleReportCollector* aReporter);
+  void CloseWorkerOnMainThread();
 
-  void AddPortIdentifier(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
-                         const MessagePortIdentifier& aPortIdentifier);
-
-  RefPtr<GenericNonExclusivePromise> GetTerminationPromise();
-
-  RefPtr<GenericPromise> MaybeSendSetServiceWorkerSkipWaitingFlag();
+  void FlushReportsOnMainThread(nsIConsoleReportCollector* aReporter);
 
  private:
   class InitializeWorkerRunnable;
 
-  class Op;
-  class SharedWorkerOp;
-
-  struct Pending {
-    nsTArray<RefPtr<Op>> mPendingOps;
-  };
-
-  struct PendingTerminated {};
-
-  struct Running {
-    ~Running();
+  ~RemoteWorkerChild();
 
-    RefPtr<WorkerPrivate> mWorkerPrivate;
-    RefPtr<WeakWorkerRef> mWorkerRef;
-  };
-
-  struct Terminated {};
-
-  using State = Variant<Pending, Running, PendingTerminated, Terminated>;
+  void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  DataMutex<State> mState;
-
-  class Op {
-   public:
-    NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
-
-    virtual ~Op() = default;
-
-    virtual bool MaybeStart(RemoteWorkerChild* aOwner, State& aState) = 0;
+  mozilla::ipc::IPCResult RecvExecOp(const RemoteWorkerOp& aOp);
 
-    virtual void Cancel() = 0;
-  };
-
-  void ActorDestroy(ActorDestroyReason) override;
-
-  mozilla::ipc::IPCResult RecvExecOp(RemoteWorkerOp&& aOp);
-
-  mozilla::ipc::IPCResult RecvExecServiceWorkerOp(
-      ServiceWorkerOpArgs&& aArgs, ExecServiceWorkerOpResolver&& aResolve);
-
-  PFetchEventOpProxyChild* AllocPFetchEventOpProxyChild(
-      const ServiceWorkerFetchEventOpArgs& aArgs);
+  // This member is a function template because DataMutex<SharedData>::AutoLock
+  // is private, yet it must be passed by const reference into ExecuteOperation.
+  // There should only be one instantiation of this template.
+  template <typename T>
+  mozilla::ipc::IPCResult ExecuteOperation(const RemoteWorkerOp&,
+                                           const T& aLock);
 
-  mozilla::ipc::IPCResult RecvPFetchEventOpProxyConstructor(
-      PFetchEventOpProxyChild* aActor,
-      const ServiceWorkerFetchEventOpArgs& aArgs) override;
-
-  bool DeallocPFetchEventOpProxyChild(PFetchEventOpProxyChild* aActor);
-
-  nsresult ExecWorkerOnMainThread(RemoteWorkerData&& aData);
-
-  void InitializeOnWorker(already_AddRefed<WorkerPrivate> aWorkerPrivate);
+  void RecvExecOpOnMainThread(const RemoteWorkerOp& aOp);
 
-  void ShutdownOnWorker();
-
-  void CreationSucceededOnAnyThread();
-
-  void CreationFailedOnAnyThread();
-
-  void CreationSucceededOrFailedOnAnyThread(bool aDidCreationSucceed);
-
-  void CloseWorkerOnMainThread(State& aState);
+  nsresult ExecWorkerOnMainThread(const RemoteWorkerData& aData);
 
   void ErrorPropagation(const ErrorValue& aValue);
 
   void ErrorPropagationDispatch(nsresult aError);
 
-  void TransitionStateToPendingTerminated(State& aState);
+  void CreationSucceededOnAnyThread();
 
-  void TransitionStateToRunning(already_AddRefed<WorkerPrivate> aWorkerPrivate,
-                                already_AddRefed<WeakWorkerRef> aWorkerRef);
-
-  void TransitionStateToTerminated();
-
-  void TransitionStateToTerminated(State& aState);
+  void CreationSucceeded();
 
-  void CancelAllPendingOps(State& aState);
-
-  void MaybeStartOp(RefPtr<Op>&& aOp);
+  void CreationFailedOnAnyThread();
 
-  MozPromiseHolder<GenericNonExclusivePromise> mTerminationPromise;
+  void CreationFailed();
 
-  const bool mIsServiceWorker;
-  const nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
+  void WorkerTerminated();
 
   // Touched on main-thread only.
   nsTArray<uint64_t> mWindowIDs;
 
+  RefPtr<WeakWorkerRef> mWorkerRef;
+  bool mIPCActive;
+
+  enum WorkerState {
+    // CreationSucceeded/CreationFailed not called yet.
+    ePending,
+
+    // The worker is not created yet, but we want to terminate as soon as
+    // possible.
+    ePendingTerminated,
+
+    // Worker up and running.
+    eRunning,
+
+    // Worker terminated.
+    eTerminated,
+  };
+
+  struct SharedData {
+    SharedData();
+
+    RefPtr<WorkerPrivate> mWorkerPrivate;
+    WorkerState mWorkerState;
+  };
+
+  DataMutex<SharedData> mSharedData;
+
+  // Touched only on the owning thread (Worker Launcher).
   struct LauncherBoundData {
-    bool mIPCActive = true;
+    nsTArray<RemoteWorkerOp> mPendingOps;
   };
 
   ThreadBound<LauncherBoundData> mLauncherData;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
--- a/dom/workers/remoteworkers/RemoteWorkerController.cpp
+++ b/dom/workers/remoteworkers/RemoteWorkerController.cpp
@@ -1,464 +1,327 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "mozilla/dom/MessagePort.h"
+#include "mozilla/dom/MessagePortParent.h"
+#include "mozilla/ipc/BackgroundParent.h"
 #include "RemoteWorkerController.h"
-
-#include <utility>
-
-#include "nsDebug.h"
-
-#include "mozilla/Assertions.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/ScopeExit.h"
-#include "mozilla/dom/MessagePortParent.h"
-#include "mozilla/dom/RemoteWorkerTypes.h"
-#include "mozilla/dom/ServiceWorkerCloneData.h"
-#include "mozilla/ipc/BackgroundParent.h"
-#include "RemoteWorkerControllerParent.h"
 #include "RemoteWorkerManager.h"
 #include "RemoteWorkerParent.h"
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
 /* static */
 already_AddRefed<RemoteWorkerController> RemoteWorkerController::Create(
     const RemoteWorkerData& aData, RemoteWorkerObserver* aObserver,
     base::ProcessId aProcessId) {
-  AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(aObserver);
 
   RefPtr<RemoteWorkerController> controller =
-      new RemoteWorkerController(aData, aObserver);
+      new RemoteWorkerController(aObserver);
 
   RefPtr<RemoteWorkerManager> manager = RemoteWorkerManager::GetOrCreate();
   MOZ_ASSERT(manager);
 
   manager->Launch(controller, aData, aProcessId);
 
   return controller.forget();
 }
 
-RemoteWorkerController::RemoteWorkerController(const RemoteWorkerData& aData,
-                                               RemoteWorkerObserver* aObserver)
-    : mObserver(aObserver),
-      mState(ePending),
-      mIsServiceWorker(aData.serviceWorkerData().type() ==
-                       OptionalServiceWorkerData::TServiceWorkerData) {
-  AssertIsInMainProcess();
+RemoteWorkerController::RemoteWorkerController(RemoteWorkerObserver* aObserver)
+    : mObserver(aObserver), mState(ePending) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
 }
 
 RemoteWorkerController::~RemoteWorkerController() {
   AssertIsOnBackgroundThread();
-  MOZ_DIAGNOSTIC_ASSERT(mPendingOps.IsEmpty());
+  MOZ_ASSERT(XRE_IsParentProcess());
 }
 
 void RemoteWorkerController::SetWorkerActor(RemoteWorkerParent* aActor) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(!mActor);
   MOZ_ASSERT(aActor);
 
   mActor = aActor;
 }
 
-void RemoteWorkerController::NoteDeadWorkerActor() {
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(mActor);
-
-  // The actor has been destroyed without a proper close() notification. Let's
-  // inform the observer.
-  if (mState == eReady) {
-    mObserver->Terminated();
-  }
-
-  mActor = nullptr;
-
-  Shutdown();
-}
-
 void RemoteWorkerController::CreationFailed() {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(mState == ePending || mState == eTerminated);
 
   if (mState == eTerminated) {
     MOZ_ASSERT(!mActor);
     MOZ_ASSERT(mPendingOps.IsEmpty());
     // Nothing to do.
     return;
   }
 
-  NoteDeadWorker();
-
+  Shutdown();
   mObserver->CreationFailed();
 }
 
 void RemoteWorkerController::CreationSucceeded() {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(mState == ePending || mState == eTerminated);
 
   if (mState == eTerminated) {
     MOZ_ASSERT(!mActor);
     MOZ_ASSERT(mPendingOps.IsEmpty());
     // Nothing to do.
     return;
   }
 
   MOZ_ASSERT(mActor);
   mState = eReady;
 
   mObserver->CreationSucceeded();
 
-  auto pendingOps = std::move(mPendingOps);
+  for (UniquePtr<Op>& op : mPendingOps) {
+    switch (op->mType) {
+      case Op::eTerminate:
+        Terminate();
+        break;
+
+      case Op::eSuspend:
+        Suspend();
+        break;
+
+      case Op::eResume:
+        Resume();
+        break;
+
+      case Op::eFreeze:
+        Freeze();
+        break;
 
-  for (auto& op : pendingOps) {
-    DebugOnly<bool> started = op->MaybeStart(this);
-    MOZ_ASSERT(started);
+      case Op::eThaw:
+        Thaw();
+        break;
+
+      case Op::ePortIdentifier:
+        AddPortIdentifier(op->mPortIdentifier);
+        break;
+
+      case Op::eAddWindowID:
+        AddWindowID(op->mWindowID);
+        break;
+
+      case Op::eRemoveWindowID:
+        RemoveWindowID(op->mWindowID);
+        break;
+
+      default:
+        MOZ_CRASH("Unknown op.");
+    }
+
+    op->Completed();
   }
+
+  mPendingOps.Clear();
 }
 
 void RemoteWorkerController::ErrorPropagation(const ErrorValue& aValue) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
 
   mObserver->ErrorReceived(aValue);
 }
 
 void RemoteWorkerController::WorkerTerminated() {
   AssertIsOnBackgroundThread();
-
-  NoteDeadWorker();
+  MOZ_ASSERT(XRE_IsParentProcess());
+  MOZ_ASSERT(mState == eReady);
 
   mObserver->Terminated();
-}
-
-void RemoteWorkerController::CancelAllPendingOps() {
-  AssertIsOnBackgroundThread();
-
-  auto pendingOps = std::move(mPendingOps);
-
-  for (auto& op : pendingOps) {
-    op->Cancel();
-  }
+  Shutdown();
 }
 
 void RemoteWorkerController::Shutdown() {
   AssertIsOnBackgroundThread();
-  Unused << NS_WARN_IF(mIsServiceWorker && !mPendingOps.IsEmpty());
-
-  if (mState == eTerminated) {
-    MOZ_ASSERT(mPendingOps.IsEmpty());
-    return;
-  }
+  MOZ_ASSERT(XRE_IsParentProcess());
+  MOZ_ASSERT(mState == ePending || mState == eReady);
 
   mState = eTerminated;
 
-  CancelAllPendingOps();
-
-  if (!mActor) {
-    return;
-  }
-
-  mActor->SetController(nullptr);
-
-  /**
-   * The "non-remote-side" of the Service Worker will have ensured that the
-   * remote worker is terminated before calling `Shutdown().`
-   */
-  if (mIsServiceWorker) {
-    mActor->MaybeSendDelete();
-  } else {
-    Unused << mActor->SendExecOp(RemoteWorkerTerminateOp());
-  }
-
-  mActor = nullptr;
-}
+  mPendingOps.Clear();
 
-void RemoteWorkerController::NoteDeadWorker() {
-  AssertIsOnBackgroundThread();
-
-  CancelAllPendingOps();
-
-  /**
-   * The "non-remote-side" of the Service Worker will initiate `Shutdown()`
-   * once it's notified that all dispatched operations have either completed
-   * or canceled. That is, it'll explicitly call `Shutdown()` later.
-   */
-  if (!mIsServiceWorker) {
-    Shutdown();
-  }
-}
-
-template <typename... Args>
-void RemoteWorkerController::MaybeStartSharedWorkerOp(Args&&... aArgs) {
-  AssertIsOnBackgroundThread();
-  MOZ_ASSERT(!mIsServiceWorker);
-
-  UniquePtr<PendingSharedWorkerOp> op =
-      MakeUnique<PendingSharedWorkerOp>(std::forward<Args>(aArgs)...);
-
-  if (!op->MaybeStart(this)) {
-    mPendingOps.AppendElement(std::move(op));
+  if (mActor) {
+    mActor->SetController(nullptr);
+    Unused << mActor->SendExecOp(RemoteWorkerTerminateOp());
+    mActor = nullptr;
   }
 }
 
 void RemoteWorkerController::AddWindowID(uint64_t aWindowID) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(aWindowID);
 
-  MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eAddWindowID, aWindowID);
+  if (mState == ePending) {
+    mPendingOps.AppendElement(new Op(Op::eAddWindowID, aWindowID));
+    return;
+  }
+
+  if (mState == eTerminated) {
+    return;
+  }
+
+  MOZ_ASSERT(mState == eReady);
+  Unused << mActor->SendExecOp(RemoteWorkerAddWindowIDOp(aWindowID));
 }
 
 void RemoteWorkerController::RemoveWindowID(uint64_t aWindowID) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(aWindowID);
 
-  MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eRemoveWindowID, aWindowID);
+  if (mState == ePending) {
+    mPendingOps.AppendElement(new Op(Op::eRemoveWindowID, aWindowID));
+    return;
+  }
+
+  if (mState == eTerminated) {
+    return;
+  }
+
+  MOZ_ASSERT(mState == eReady);
+  Unused << mActor->SendExecOp(RemoteWorkerRemoveWindowIDOp(aWindowID));
 }
 
 void RemoteWorkerController::AddPortIdentifier(
     const MessagePortIdentifier& aPortIdentifier) {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
 
-  MaybeStartSharedWorkerOp(aPortIdentifier);
+  if (mState == ePending) {
+    mPendingOps.AppendElement(new Op(aPortIdentifier));
+    return;
+  }
+
+  if (mState == eTerminated) {
+    return;
+  }
+
+  MOZ_ASSERT(mState == eReady);
+  Unused << mActor->SendExecOp(RemoteWorkerPortIdentifierOp(aPortIdentifier));
+}
+
+void RemoteWorkerController::ForgetActorAndTerminate() {
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
+
+  // The actor has been destroyed without a proper close() notification. Let's
+  // inform the observer.
+  if (mState == eReady) {
+    mObserver->Terminated();
+  }
+
+  mActor = nullptr;
+  Terminate();
 }
 
 void RemoteWorkerController::Terminate() {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
 
-  MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eTerminate);
+  if (mState == eTerminated) {
+    return;
+  }
+
+  Shutdown();
 }
 
 void RemoteWorkerController::Suspend() {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
 
-  MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eSuspend);
+  if (mState == ePending) {
+    mPendingOps.AppendElement(new Op(Op::eSuspend));
+    return;
+  }
+
+  if (mState == eTerminated) {
+    return;
+  }
+
+  MOZ_ASSERT(mState == eReady);
+  Unused << mActor->SendExecOp(RemoteWorkerSuspendOp());
 }
 
 void RemoteWorkerController::Resume() {
   AssertIsOnBackgroundThread();
+  MOZ_ASSERT(XRE_IsParentProcess());
 
-  MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eResume);
+  if (mState == ePending) {
+    mPendingOps.AppendElement(new Op(Op::eResume));
+    return;