Bug 1231213 - Implement PRemoteWorkerController IPDL protocol and RemoteWorkerController{Parent,Child}. r=asuth
☠☠ backed out by 3cf55b7f12f2 ☠ ☠
authorPerry Jiang <perry@mozilla.com>
Wed, 14 Aug 2019 16:19:57 +0000
changeset 488069 11f010e6d6e7166b92c2638832896962bd8a71a7
parent 488068 6ed55807374f0ba63a36990d06200f77baf713a6
child 488070 0b03a19a6dc141f49ead7555b200e5b7498124c0
push id113900
push usercbrindusan@mozilla.com
push dateThu, 15 Aug 2019 09:53:50 +0000
treeherdermozilla-inbound@0db07ff50ab5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1231213
milestone70.0a1
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
Bug 1231213 - Implement PRemoteWorkerController IPDL protocol and RemoteWorkerController{Parent,Child}. r=asuth Differential Revision: https://phabricator.services.mozilla.com/D26168
dom/workers/remoteworkers/PRemoteWorkerController.ipdl
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/moz.build
ipc/glue/BackgroundChildImpl.cpp
ipc/glue/BackgroundChildImpl.h
ipc/glue/BackgroundParentImpl.cpp
ipc/glue/BackgroundParentImpl.h
ipc/glue/PBackground.ipdl
new file mode 100644
--- /dev/null
+++ b/dom/workers/remoteworkers/PRemoteWorkerController.ipdl
@@ -0,0 +1,33 @@
+/* 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 RemoteWorkerTypes;
+include ServiceWorkerOpArgs;
+
+namespace mozilla {
+namespace dom {
+
+protocol PRemoteWorkerController {
+  manager PBackground;
+
+ child:
+  async CreationFailed();
+
+  async CreationSucceeded();
+
+  async ErrorReceived(ErrorValue aError);
+
+  async Terminated();
+
+ parent:
+  async __delete__();
+
+  async Shutdown() returns (bool aOk);
+
+};
+
+}  // namespace dom
+}  // namespace mozilla
--- a/dom/workers/remoteworkers/RemoteWorkerController.cpp
+++ b/dom/workers/remoteworkers/RemoteWorkerController.cpp
@@ -1,16 +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 "mozilla/dom/MessagePort.h"
 #include "mozilla/dom/MessagePortParent.h"
+#include "mozilla/dom/RemoteWorkerTypes.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "RemoteWorkerController.h"
 #include "RemoteWorkerManager.h"
 #include "RemoteWorkerParent.h"
 
 namespace mozilla {
 
 using namespace ipc;
@@ -21,28 +22,33 @@ namespace dom {
 already_AddRefed<RemoteWorkerController> RemoteWorkerController::Create(
     const RemoteWorkerData& aData, RemoteWorkerObserver* aObserver,
     base::ProcessId aProcessId) {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(aObserver);
 
   RefPtr<RemoteWorkerController> controller =
-      new RemoteWorkerController(aObserver);
+      new RemoteWorkerController(aData, aObserver);
 
   RefPtr<RemoteWorkerManager> manager = RemoteWorkerManager::GetOrCreate();
   MOZ_ASSERT(manager);
 
   manager->Launch(controller, aData, aProcessId);
 
   return controller.forget();
 }
 
-RemoteWorkerController::RemoteWorkerController(RemoteWorkerObserver* aObserver)
-    : mObserver(aObserver), mState(ePending) {
+RemoteWorkerController::RemoteWorkerController(const RemoteWorkerData& aData,
+                                               RemoteWorkerObserver* aObserver)
+    : mObserver(aObserver),
+      mState(ePending),
+      mIsServiceWorker(aData.serviceWorkerData().type() ==
+                       OptionalServiceWorkerData::TServiceWorkerData) {
+  AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(XRE_IsParentProcess());
 }
 
 RemoteWorkerController::~RemoteWorkerController() {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(XRE_IsParentProcess());
 }
--- a/dom/workers/remoteworkers/RemoteWorkerController.h
+++ b/dom/workers/remoteworkers/RemoteWorkerController.h
@@ -75,16 +75,18 @@ namespace dom {
  * 8. The RemoteWorkerParent actor is passed to the RemoteWorkerController.
  * 9. RemoteWorkerController now is ready to continue and it called
  *    RemoteWorkerObserver to inform that the operation is completed.
  *    In case there were pending operations, they are now executed.
  */
 
 class ErrorValue;
 class MessagePortIdentifier;
+class RemoteWorkerControllerParent;
+class RemoteWorkerData;
 class RemoteWorkerManager;
 class RemoteWorkerParent;
 
 class RemoteWorkerObserver {
  public:
   NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
 
   virtual void CreationFailed() = 0;
@@ -92,16 +94,17 @@ class RemoteWorkerObserver {
   virtual void CreationSucceeded() = 0;
 
   virtual void ErrorReceived(const ErrorValue& aValue) = 0;
 
   virtual void Terminated() = 0;
 };
 
 class RemoteWorkerController final {
+  friend class RemoteWorkerControllerParent;
   friend class RemoteWorkerManager;
   friend class RemoteWorkerParent;
 
  public:
   NS_INLINE_DECL_REFCOUNTING(RemoteWorkerController)
 
   static already_AddRefed<RemoteWorkerController> Create(
       const RemoteWorkerData& aData, RemoteWorkerObserver* aObserver,
@@ -119,17 +122,19 @@ class RemoteWorkerController final {
 
   void Resume();
 
   void Freeze();
 
   void Thaw();
 
  private:
-  explicit RemoteWorkerController(RemoteWorkerObserver* aObserver);
+  RemoteWorkerController(const RemoteWorkerData& aData,
+                         RemoteWorkerObserver* aObserver);
+
   ~RemoteWorkerController();
 
   void SetWorkerActor(RemoteWorkerParent* aActor);
 
   void ErrorPropagation(const ErrorValue& aValue);
 
   void WorkerTerminated();
 
@@ -145,16 +150,18 @@ class RemoteWorkerController final {
   RefPtr<RemoteWorkerParent> mActor;
 
   enum {
     ePending,
     eReady,
     eTerminated,
   } mState;
 
+  const bool mIsServiceWorker;
+
   struct Op {
     enum Type {
       eTerminate,
       eSuspend,
       eResume,
       eFreeze,
       eThaw,
       ePortIdentifier,
new file mode 100644
--- /dev/null
+++ b/dom/workers/remoteworkers/RemoteWorkerControllerChild.cpp
@@ -0,0 +1,111 @@
+/* -*- 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 "RemoteWorkerControllerChild.h"
+
+#include <utility>
+
+#include "MainThreadUtils.h"
+#include "nsError.h"
+#include "nsThreadUtils.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/Unused.h"
+
+namespace mozilla {
+
+using ipc::IPCResult;
+
+namespace dom {
+
+RemoteWorkerControllerChild::RemoteWorkerControllerChild(
+    RefPtr<RemoteWorkerObserver> aObserver)
+    : mObserver(std::move(aObserver)) {
+  AssertIsOnMainThread();
+  MOZ_ASSERT(mObserver);
+}
+
+void RemoteWorkerControllerChild::ActorDestroy(ActorDestroyReason aReason) {
+  AssertIsOnMainThread();
+
+  mIPCActive = false;
+
+  if (NS_WARN_IF(mObserver)) {
+    mObserver->ErrorReceived(NS_ERROR_DOM_ABORT_ERR);
+  }
+}
+
+IPCResult RemoteWorkerControllerChild::RecvCreationFailed() {
+  AssertIsOnMainThread();
+
+  if (mObserver) {
+    mObserver->CreationFailed();
+  }
+
+  return IPC_OK();
+}
+
+IPCResult RemoteWorkerControllerChild::RecvCreationSucceeded() {
+  AssertIsOnMainThread();
+
+  if (mObserver) {
+    mObserver->CreationSucceeded();
+  }
+
+  return IPC_OK();
+}
+
+IPCResult RemoteWorkerControllerChild::RecvErrorReceived(
+    const ErrorValue& aError) {
+  AssertIsOnMainThread();
+
+  if (mObserver) {
+    mObserver->ErrorReceived(aError);
+  }
+
+  return IPC_OK();
+}
+
+IPCResult RemoteWorkerControllerChild::RecvTerminated() {
+  AssertIsOnMainThread();
+
+  if (mObserver) {
+    mObserver->Terminated();
+  }
+
+  return IPC_OK();
+}
+
+void RemoteWorkerControllerChild::RevokeObserver(
+    RemoteWorkerObserver* aObserver) {
+  AssertIsOnMainThread();
+  MOZ_ASSERT(aObserver);
+  MOZ_ASSERT(aObserver == mObserver);
+
+  mObserver = nullptr;
+}
+
+void RemoteWorkerControllerChild::MaybeSendDelete() {
+  AssertIsOnMainThread();
+
+  if (!mIPCActive) {
+    return;
+  }
+
+  RefPtr<RemoteWorkerControllerChild> self = this;
+
+  SendShutdown()->Then(
+      GetCurrentThreadSerialEventTarget(), __func__,
+      [self = std::move(self)](const ShutdownPromise::ResolveOrRejectValue&) {
+        if (self->mIPCActive) {
+          Unused << self->Send__delete__(self);
+        }
+      });
+}
+
+}  // namespace dom
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/workers/remoteworkers/RemoteWorkerControllerChild.h
@@ -0,0 +1,54 @@
+/* -*- 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_remoteworkercontrollerchild_h__
+#define mozilla_dom_remoteworkercontrollerchild_h__
+
+#include "nsISupportsImpl.h"
+
+#include "RemoteWorkerController.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/dom/PRemoteWorkerControllerChild.h"
+
+namespace mozilla {
+namespace dom {
+
+class RemoteWorkerControllerChild final : public PRemoteWorkerControllerChild {
+  friend class PRemoteWorkerControllerChild;
+
+ public:
+  NS_INLINE_DECL_REFCOUNTING(RemoteWorkerControllerChild)
+
+  explicit RemoteWorkerControllerChild(RefPtr<RemoteWorkerObserver> aObserver);
+
+  void Initialize();
+
+  void RevokeObserver(RemoteWorkerObserver* aObserver);
+
+  void MaybeSendDelete();
+
+ private:
+  ~RemoteWorkerControllerChild() = default;
+
+  void ActorDestroy(ActorDestroyReason aReason) override;
+
+  mozilla::ipc::IPCResult RecvCreationFailed();
+
+  mozilla::ipc::IPCResult RecvCreationSucceeded();
+
+  mozilla::ipc::IPCResult RecvErrorReceived(const ErrorValue& aError);
+
+  mozilla::ipc::IPCResult RecvTerminated();
+
+  RefPtr<RemoteWorkerObserver> mObserver;
+
+  bool mIPCActive = true;
+};
+
+}  // namespace dom
+}  // namespace mozilla
+
+#endif  // mozilla_dom_remoteworkercontrollerchild_h__
new file mode 100644
--- /dev/null
+++ b/dom/workers/remoteworkers/RemoteWorkerControllerParent.cpp
@@ -0,0 +1,127 @@
+/* -*- 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 "RemoteWorkerControllerParent.h"
+
+#include <utility>
+
+#include "nsCOMPtr.h"
+#include "nsDebug.h"
+#include "nsError.h"
+#include "nsThreadUtils.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Unused.h"
+#include "mozilla/ipc/BackgroundParent.h"
+
+namespace mozilla {
+
+using namespace ipc;
+
+namespace dom {
+
+RemoteWorkerControllerParent::RemoteWorkerControllerParent(
+    const RemoteWorkerData& aRemoteWorkerData)
+    : mRemoteWorkerController(RemoteWorkerController::Create(
+          aRemoteWorkerData, this, 0 /* random process ID */)) {
+  AssertIsInMainProcess();
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(mRemoteWorkerController);
+}
+
+RefPtr<RemoteWorkerParent> RemoteWorkerControllerParent::GetRemoteWorkerParent()
+    const {
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(mRemoteWorkerController);
+
+  return mRemoteWorkerController->mActor;
+}
+
+RemoteWorkerControllerParent::~RemoteWorkerControllerParent() {
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(!mIPCActive);
+  MOZ_ASSERT(!mRemoteWorkerController);
+}
+
+IPCResult RemoteWorkerControllerParent::RecvShutdown(
+    ShutdownResolver&& aResolve) {
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(mIPCActive);
+  MOZ_ASSERT(mRemoteWorkerController);
+
+  mIPCActive = false;
+
+  mRemoteWorkerController->Shutdown();
+  mRemoteWorkerController = nullptr;
+
+  aResolve(true);
+
+  return IPC_OK();
+}
+
+IPCResult RemoteWorkerControllerParent::Recv__delete__() {
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(!mIPCActive);
+  MOZ_ASSERT(!mRemoteWorkerController);
+
+  return IPC_OK();
+}
+
+void RemoteWorkerControllerParent::ActorDestroy(ActorDestroyReason aReason) {
+  AssertIsOnBackgroundThread();
+
+  if (NS_WARN_IF(mIPCActive)) {
+    mIPCActive = false;
+  }
+
+  if (NS_WARN_IF(mRemoteWorkerController)) {
+    mRemoteWorkerController->Shutdown();
+    mRemoteWorkerController = nullptr;
+  }
+}
+
+void RemoteWorkerControllerParent::CreationFailed() {
+  AssertIsOnBackgroundThread();
+
+  if (!mIPCActive) {
+    return;
+  }
+
+  Unused << SendCreationFailed();
+}
+
+void RemoteWorkerControllerParent::CreationSucceeded() {
+  AssertIsOnBackgroundThread();
+
+  if (!mIPCActive) {
+    return;
+  }
+
+  Unused << SendCreationSucceeded();
+}
+
+void RemoteWorkerControllerParent::ErrorReceived(const ErrorValue& aValue) {
+  AssertIsOnBackgroundThread();
+
+  if (!mIPCActive) {
+    return;
+  }
+
+  Unused << SendErrorReceived(aValue);
+}
+
+void RemoteWorkerControllerParent::Terminated() {
+  AssertIsOnBackgroundThread();
+
+  if (!mIPCActive) {
+    return;
+  }
+
+  Unused << SendTerminated();
+}
+
+}  // namespace dom
+}  // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/workers/remoteworkers/RemoteWorkerControllerParent.h
@@ -0,0 +1,59 @@
+/* -*- 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_remoteworkercontrollerparent_h__
+#define mozilla_dom_remoteworkercontrollerparent_h__
+
+#include <functional>
+
+#include "nsISupportsImpl.h"
+
+#include "RemoteWorkerController.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/dom/PRemoteWorkerControllerParent.h"
+
+namespace mozilla {
+namespace dom {
+
+class RemoteWorkerControllerParent final : public PRemoteWorkerControllerParent,
+                                           public RemoteWorkerObserver {
+  friend class PRemoteWorkerControllerParent;
+
+ public:
+  NS_INLINE_DECL_REFCOUNTING(RemoteWorkerControllerParent, override)
+
+  explicit RemoteWorkerControllerParent(
+      const RemoteWorkerData& aRemoteWorkerData);
+
+  // Returns the corresponding RemoteWorkerParent (if any).
+  RefPtr<RemoteWorkerParent> GetRemoteWorkerParent() const;
+
+ private:
+  ~RemoteWorkerControllerParent();
+
+  mozilla::ipc::IPCResult RecvShutdown(ShutdownResolver&& aResolve);
+
+  mozilla::ipc::IPCResult Recv__delete__() override;
+
+  void ActorDestroy(ActorDestroyReason aReason) override;
+
+  void CreationFailed() override;
+
+  void CreationSucceeded() override;
+
+  void ErrorReceived(const ErrorValue& aValue) override;
+
+  void Terminated() override;
+
+  RefPtr<RemoteWorkerController> mRemoteWorkerController;
+
+  bool mIPCActive = true;
+};
+
+}  // namespace dom
+}  // namespace mozilla
+
+#endif  // mozilla_dom_remoteworkercontrollerparent_h__
--- a/dom/workers/remoteworkers/moz.build
+++ b/dom/workers/remoteworkers/moz.build
@@ -2,37 +2,42 @@
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS.mozilla.dom += [
     'RemoteWorkerChild.h',
     'RemoteWorkerController.h',
+    'RemoteWorkerControllerChild.h',
+    'RemoteWorkerControllerParent.h',
     'RemoteWorkerParent.h',
     'RemoteWorkerService.h',
     'RemoteWorkerServiceChild.h',
     'RemoteWorkerServiceParent.h',
 ]
 
 UNIFIED_SOURCES += [
     'RemoteWorkerChild.cpp',
     'RemoteWorkerController.cpp',
+    'RemoteWorkerControllerChild.cpp',
+    'RemoteWorkerControllerParent.cpp',
     'RemoteWorkerManager.cpp',
     'RemoteWorkerParent.cpp',
     'RemoteWorkerService.cpp',
     'RemoteWorkerServiceChild.cpp',
     'RemoteWorkerServiceParent.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/xpcom/build',
 ]
 
 IPDL_SOURCES += [
     'PRemoteWorker.ipdl',
+    'PRemoteWorkerController.ipdl',
     'PRemoteWorkerService.ipdl',
     'RemoteWorkerTypes.ipdlh',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -30,16 +30,17 @@
 #include "mozilla/dom/PendingIPCBlobChild.h"
 #include "mozilla/dom/TemporaryIPCBlobChild.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
 #include "mozilla/dom/IPCBlobUtils.h"
 #include "mozilla/dom/quota/PQuotaChild.h"
 #include "mozilla/dom/RemoteWorkerChild.h"
+#include "mozilla/dom/RemoteWorkerControllerChild.h"
 #include "mozilla/dom/RemoteWorkerServiceChild.h"
 #include "mozilla/dom/SharedWorkerChild.h"
 #include "mozilla/dom/StorageIPC.h"
 #include "mozilla/dom/GamepadEventChannelChild.h"
 #include "mozilla/dom/GamepadTestChannelChild.h"
 #include "mozilla/dom/LocalStorage.h"
 #include "mozilla/dom/MessagePortChild.h"
 #include "mozilla/dom/ServiceWorkerActors.h"
@@ -337,16 +338,33 @@ IPCResult BackgroundChildImpl::RecvPRemo
 
 bool BackgroundChildImpl::DeallocPRemoteWorkerChild(
     dom::PRemoteWorkerChild* aActor) {
   RefPtr<dom::RemoteWorkerChild> actor =
       dont_AddRef(static_cast<dom::RemoteWorkerChild*>(aActor));
   return true;
 }
 
+dom::PRemoteWorkerControllerChild*
+BackgroundChildImpl::AllocPRemoteWorkerControllerChild(
+    const dom::RemoteWorkerData& aRemoteWorkerData) {
+  MOZ_CRASH(
+      "PRemoteWorkerControllerChild actors must be manually constructed!");
+  return nullptr;
+}
+
+bool BackgroundChildImpl::DeallocPRemoteWorkerControllerChild(
+    dom::PRemoteWorkerControllerChild* aActor) {
+  MOZ_ASSERT(aActor);
+
+  RefPtr<dom::RemoteWorkerControllerChild> actor =
+      dont_AddRef(static_cast<dom::RemoteWorkerControllerChild*>(aActor));
+  return true;
+}
+
 dom::PRemoteWorkerServiceChild*
 BackgroundChildImpl::AllocPRemoteWorkerServiceChild() {
   RefPtr<dom::RemoteWorkerServiceChild> agent =
       new dom::RemoteWorkerServiceChild();
   return agent.forget().take();
 }
 
 bool BackgroundChildImpl::DeallocPRemoteWorkerServiceChild(
--- a/ipc/glue/BackgroundChildImpl.h
+++ b/ipc/glue/BackgroundChildImpl.h
@@ -136,16 +136,23 @@ class BackgroundChildImpl : public PBack
       const RemoteWorkerData& aData) override;
 
   virtual mozilla::ipc::IPCResult RecvPRemoteWorkerConstructor(
       PRemoteWorkerChild* aActor, const RemoteWorkerData& aData) override;
 
   virtual bool DeallocPRemoteWorkerChild(
       mozilla::dom::PRemoteWorkerChild* aActor) override;
 
+  virtual mozilla::dom::PRemoteWorkerControllerChild*
+  AllocPRemoteWorkerControllerChild(
+      const mozilla::dom::RemoteWorkerData& aRemoteWorkerData) override;
+
+  virtual bool DeallocPRemoteWorkerControllerChild(
+      mozilla::dom::PRemoteWorkerControllerChild* aActor) override;
+
   virtual mozilla::dom::PRemoteWorkerServiceChild*
   AllocPRemoteWorkerServiceChild() override;
 
   virtual bool DeallocPRemoteWorkerServiceChild(
       mozilla::dom::PRemoteWorkerServiceChild* aActor) override;
 
   virtual mozilla::dom::PSharedWorkerChild* AllocPSharedWorkerChild(
       const mozilla::dom::RemoteWorkerData& aData, const uint64_t& aWindowID,
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -35,16 +35,17 @@
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/ActorsParent.h"
 #include "mozilla/dom/IPCBlobInputStreamParent.h"
 #include "mozilla/dom/IPCBlobUtils.h"
 #include "mozilla/dom/localstorage/ActorsParent.h"
 #include "mozilla/dom/quota/ActorsParent.h"
 #include "mozilla/dom/simpledb/ActorsParent.h"
 #include "mozilla/dom/RemoteWorkerParent.h"
+#include "mozilla/dom/RemoteWorkerControllerParent.h"
 #include "mozilla/dom/RemoteWorkerServiceParent.h"
 #include "mozilla/dom/ReportingHeader.h"
 #include "mozilla/dom/SharedWorkerParent.h"
 #include "mozilla/dom/StorageIPC.h"
 #include "mozilla/dom/MIDIManagerParent.h"
 #include "mozilla/dom/MIDIPortParent.h"
 #include "mozilla/dom/MIDIPlatformService.h"
 #include "mozilla/ipc/BackgroundParent.h"
@@ -492,16 +493,39 @@ BackgroundParentImpl::AllocPRemoteWorker
 
 bool BackgroundParentImpl::DeallocPRemoteWorkerParent(
     mozilla::dom::PRemoteWorkerParent* aActor) {
   RefPtr<mozilla::dom::RemoteWorkerParent> actor =
       dont_AddRef(static_cast<mozilla::dom::RemoteWorkerParent*>(aActor));
   return true;
 }
 
+dom::PRemoteWorkerControllerParent*
+BackgroundParentImpl::AllocPRemoteWorkerControllerParent(
+    const dom::RemoteWorkerData& aRemoteWorkerData) {
+  RefPtr<dom::RemoteWorkerControllerParent> actor =
+      new dom::RemoteWorkerControllerParent(aRemoteWorkerData);
+  return actor.forget().take();
+}
+
+IPCResult BackgroundParentImpl::RecvPRemoteWorkerControllerConstructor(
+    dom::PRemoteWorkerControllerParent* aActor,
+    const dom::RemoteWorkerData& aRemoteWorkerData) {
+  MOZ_ASSERT(aActor);
+
+  return IPC_OK();
+}
+
+bool BackgroundParentImpl::DeallocPRemoteWorkerControllerParent(
+    dom::PRemoteWorkerControllerParent* aActor) {
+  RefPtr<dom::RemoteWorkerControllerParent> actor =
+      dont_AddRef(static_cast<dom::RemoteWorkerControllerParent*>(aActor));
+  return true;
+}
+
 mozilla::dom::PRemoteWorkerServiceParent*
 BackgroundParentImpl::AllocPRemoteWorkerServiceParent() {
   return new mozilla::dom::RemoteWorkerServiceParent();
 }
 
 IPCResult BackgroundParentImpl::RecvPRemoteWorkerServiceConstructor(
     PRemoteWorkerServiceParent* aActor) {
   mozilla::dom::RemoteWorkerServiceParent* actor =
--- a/ipc/glue/BackgroundParentImpl.h
+++ b/ipc/glue/BackgroundParentImpl.h
@@ -166,16 +166,27 @@ class BackgroundParentImpl : public PBac
 
   virtual bool DeallocPFileCreatorParent(PFileCreatorParent* aActor) override;
 
   virtual mozilla::dom::PRemoteWorkerParent* AllocPRemoteWorkerParent(
       const RemoteWorkerData& aData) override;
 
   virtual bool DeallocPRemoteWorkerParent(PRemoteWorkerParent* aActor) override;
 
+  virtual mozilla::dom::PRemoteWorkerControllerParent*
+  AllocPRemoteWorkerControllerParent(
+      const mozilla::dom::RemoteWorkerData& aRemoteWorkerData) override;
+
+  virtual mozilla::ipc::IPCResult RecvPRemoteWorkerControllerConstructor(
+      mozilla::dom::PRemoteWorkerControllerParent* aActor,
+      const mozilla::dom::RemoteWorkerData& aRemoteWorkerData) override;
+
+  virtual bool DeallocPRemoteWorkerControllerParent(
+      mozilla::dom::PRemoteWorkerControllerParent* aActor) override;
+
   virtual mozilla::dom::PRemoteWorkerServiceParent*
   AllocPRemoteWorkerServiceParent() override;
 
   virtual mozilla::ipc::IPCResult RecvPRemoteWorkerServiceConstructor(
       PRemoteWorkerServiceParent* aActor) override;
 
   virtual bool DeallocPRemoteWorkerServiceParent(
       PRemoteWorkerServiceParent* aActor) override;
--- a/ipc/glue/PBackground.ipdl
+++ b/ipc/glue/PBackground.ipdl
@@ -22,16 +22,17 @@ include protocol PFileDescriptorSet;
 include protocol PFileSystemRequest;
 include protocol PGamepadEventChannel;
 include protocol PGamepadTestChannel;
 include protocol PHttpBackgroundChannel;
 include protocol PIPCBlobInputStream;
 include protocol PMediaTransport;
 include protocol PPendingIPCBlob;
 include protocol PRemoteWorker;
+include protocol PRemoteWorkerController;
 include protocol PRemoteWorkerService;
 include protocol PSharedWorker;
 include protocol PTemporaryIPCBlob;
 include protocol PFileCreator;
 include protocol PMessagePort;
 include protocol PCameras;
 include protocol PMIDIManager;
 include protocol PMIDIPort;
@@ -89,16 +90,17 @@ sync protocol PBackground
   manages PFileSystemRequest;
   manages PGamepadEventChannel;
   manages PGamepadTestChannel;
   manages PHttpBackgroundChannel;
   manages PIPCBlobInputStream;
   manages PMediaTransport;
   manages PPendingIPCBlob;
   manages PRemoteWorker;
+  manages PRemoteWorkerController;
   manages PRemoteWorkerService;
   manages PSharedWorker;
   manages PTemporaryIPCBlob;
   manages PFileCreator;
   manages PMessagePort;
   manages PCameras;
   manages PMIDIManager;
   manages PMIDIPort;
@@ -211,16 +213,18 @@ parent:
   async PMIDIPort(MIDIPortInfo portInfo, bool sysexEnabled);
 
   // This method is used to propagate storage activities from the child actor
   // to the parent actor. See StorageActivityService.
   async StorageActivity(PrincipalInfo principalInfo);
 
   async PServiceWorker(IPCServiceWorkerDescriptor aDescriptor);
 
+  async PRemoteWorkerController(RemoteWorkerData aData);
+
   async PRemoteWorkerService();
 
   async PServiceWorkerContainer();
 
   async PServiceWorkerRegistration(IPCServiceWorkerRegistrationDescriptor aDescriptor);
 
   async PEndpointForReport(nsString aGroupName, PrincipalInfo aPrincipalInfo);