Bug 1301259 - Part1: Move session info structures to PresentationServiceBase class, r=smaug
authorKershaw Chang <kechang@mozilla.com>
Wed, 28 Sep 2016 23:35:00 +0200
changeset 358672 c572919bea3524d38e1a3364a4acba332910b84a
parent 358671 6e6856e101c6e70c5f2f19089719f3e6df2bc3db
child 358673 f8797c70734845bba0e918977e276f6b76e9769e
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1301259
milestone52.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 1301259 - Part1: Move session info structures to PresentationServiceBase class, r=smaug
dom/presentation/PresentationService.cpp
dom/presentation/PresentationService.h
dom/presentation/PresentationServiceBase.cpp
dom/presentation/PresentationServiceBase.h
dom/presentation/ipc/PresentationIPCService.cpp
dom/presentation/ipc/PresentationIPCService.h
dom/presentation/moz.build
--- a/dom/presentation/PresentationService.cpp
+++ b/dom/presentation/PresentationService.cpp
@@ -256,20 +256,19 @@ PresentationDeviceRequest::Cancel(nsresu
 {
   return mCallback->NotifyError(aReason);
 }
 
 /*
  * Implementation of PresentationService
  */
 
-NS_IMPL_ISUPPORTS_INHERITED(PresentationService,
-                            PresentationServiceBase,
-                            nsIPresentationService,
-                            nsIObserver)
+NS_IMPL_ISUPPORTS(PresentationService,
+                  nsIPresentationService,
+                  nsIObserver)
 
 PresentationService::PresentationService()
   : mIsAvailable(false)
 {
 }
 
 PresentationService::~PresentationService()
 {
--- a/dom/presentation/PresentationService.h
+++ b/dom/presentation/PresentationService.h
@@ -19,44 +19,29 @@ class nsIURI;
 class nsIPresentationSessionTransportBuilder;
 
 namespace mozilla {
 namespace dom {
 
 class PresentationDeviceRequest;
 class PresentationRespondingInfo;
 
-class PresentationService final : public nsIPresentationService
-                                , public nsIObserver
-                                , public PresentationServiceBase
+class PresentationService final
+                      : public nsIPresentationService
+                      , public nsIObserver
+                      , public PresentationServiceBase<PresentationSessionInfo>
 {
 public:
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIPRESENTATIONSERVICE
 
   PresentationService();
   bool Init();
 
-  already_AddRefed<PresentationSessionInfo>
-  GetSessionInfo(const nsAString& aSessionId, const uint8_t aRole)
-  {
-    MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
-               aRole == nsIPresentationService::ROLE_RECEIVER);
-
-    RefPtr<PresentationSessionInfo> info;
-    if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
-      return mSessionInfoAtController.Get(aSessionId, getter_AddRefs(info)) ?
-             info.forget() : nullptr;
-    } else {
-      return mSessionInfoAtReceiver.Get(aSessionId, getter_AddRefs(info)) ?
-             info.forget() : nullptr;
-    }
-  }
-
   bool IsSessionAccessible(const nsAString& aSessionId,
                            const uint8_t aRole,
                            base::ProcessId aProcessId);
 
 private:
   friend class PresentationDeviceRequest;
 
   virtual ~PresentationService();
@@ -71,16 +56,14 @@ private:
   // This is meant to be called by PresentationDeviceRequest.
   already_AddRefed<PresentationSessionInfo>
   CreateControllingSessionInfo(const nsAString& aUrl,
                                const nsAString& aSessionId,
                                uint64_t aWindowId);
 
   bool mIsAvailable;
   nsTObserverArray<nsCOMPtr<nsIPresentationAvailabilityListener>> mAvailabilityListeners;
-  nsRefPtrHashtable<nsStringHashKey, PresentationSessionInfo> mSessionInfoAtController;
-  nsRefPtrHashtable<nsStringHashKey, PresentationSessionInfo> mSessionInfoAtReceiver;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PresentationService_h
deleted file mode 100644
--- a/dom/presentation/PresentationServiceBase.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et ft=cpp : */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "PresentationServiceBase.h"
-
-#include "nsString.h"
-
-namespace mozilla {
-namespace dom {
-
-NS_IMPL_ISUPPORTS0(PresentationServiceBase)
-
-nsresult
-PresentationServiceBase::SessionIdManager::GetWindowId(
-                                                   const nsAString& aSessionId,
-                                                   uint64_t* aWindowId)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (mRespondingWindowIds.Get(aSessionId, aWindowId)) {
-    return NS_OK;
-  }
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-nsresult
-PresentationServiceBase::SessionIdManager::GetSessionIds(
-                                               uint64_t aWindowId,
-                                               nsTArray<nsString>& aSessionIds)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  nsTArray<nsString>* sessionIdArray;
-  if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  aSessionIds.Assign(*sessionIdArray);
-  return NS_OK;
-}
-
-void
-PresentationServiceBase::SessionIdManager::AddSessionId(
-                                                   uint64_t aWindowId,
-                                                   const nsAString& aSessionId)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  if (NS_WARN_IF(aWindowId == 0)) {
-    return;
-  }
-
-  nsTArray<nsString>* sessionIdArray;
-  if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) {
-    sessionIdArray = new nsTArray<nsString>();
-    mRespondingSessionIds.Put(aWindowId, sessionIdArray);
-  }
-
-  sessionIdArray->AppendElement(nsString(aSessionId));
-  mRespondingWindowIds.Put(aSessionId, aWindowId);
-}
-
-void
-PresentationServiceBase::SessionIdManager::RemoveSessionId(
-                                                   const nsAString& aSessionId)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  uint64_t windowId = 0;
-  if (mRespondingWindowIds.Get(aSessionId, &windowId)) {
-    mRespondingWindowIds.Remove(aSessionId);
-    nsTArray<nsString>* sessionIdArray;
-    if (mRespondingSessionIds.Get(windowId, &sessionIdArray)) {
-      sessionIdArray->RemoveElement(nsString(aSessionId));
-      if (sessionIdArray->IsEmpty()) {
-        mRespondingSessionIds.Remove(windowId);
-      }
-    }
-  }
-}
-
-nsresult
-PresentationServiceBase::SessionIdManager::UpdateWindowId(
-                                                   const nsAString& aSessionId,
-                                                   const uint64_t aWindowId)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RemoveSessionId(aSessionId);
-  AddSessionId(aWindowId, aSessionId);
-  return NS_OK;
-}
-
-nsresult
-PresentationServiceBase::GetWindowIdBySessionIdInternal(
-                                                   const nsAString& aSessionId,
-                                                   uint8_t aRole,
-                                                   uint64_t* aWindowId)
-{
-  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
-             aRole == nsIPresentationService::ROLE_RECEIVER);
-
-  if (NS_WARN_IF(!aWindowId)) {
-    return NS_ERROR_INVALID_POINTER;
-  }
-
-  if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
-    return mControllerSessionIdManager.GetWindowId(aSessionId, aWindowId);
-  }
-
-  return mReceiverSessionIdManager.GetWindowId(aSessionId, aWindowId);
-}
-
-void
-PresentationServiceBase::AddRespondingSessionId(uint64_t aWindowId,
-                                                const nsAString& aSessionId,
-                                                uint8_t aRole)
-{
-  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
-             aRole == nsIPresentationService::ROLE_RECEIVER);
-
-  if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
-    mControllerSessionIdManager.AddSessionId(aWindowId, aSessionId);
-  } else {
-    mReceiverSessionIdManager.AddSessionId(aWindowId, aSessionId);
-  }
-}
-
-void
-PresentationServiceBase::RemoveRespondingSessionId(const nsAString& aSessionId,
-                                                   uint8_t aRole)
-{
-  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
-             aRole == nsIPresentationService::ROLE_RECEIVER);
-
-  if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
-    mControllerSessionIdManager.RemoveSessionId(aSessionId);
-  } else {
-    mReceiverSessionIdManager.RemoveSessionId(aSessionId);
-  }
-}
-
-nsresult
-PresentationServiceBase::UpdateWindowIdBySessionIdInternal(
-                                                   const nsAString& aSessionId,
-                                                   uint8_t aRole,
-                                                   const uint64_t aWindowId)
-{
-  MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
-             aRole == nsIPresentationService::ROLE_RECEIVER);
-
-  if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
-    return mControllerSessionIdManager.UpdateWindowId(aSessionId, aWindowId);
-  }
-
-  return mReceiverSessionIdManager.UpdateWindowId(aSessionId, aWindowId);
-}
-
-} // namespace dom
-} // namespace mozilla
--- a/dom/presentation/PresentationServiceBase.h
+++ b/dom/presentation/PresentationServiceBase.h
@@ -3,55 +3,128 @@
 /* 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_PresentationServiceBase_h
 #define mozilla_dom_PresentationServiceBase_h
 
 #include "nsClassHashtable.h"
+#include "nsIPresentationService.h"
 #include "nsRefPtrHashtable.h"
+#include "nsString.h"
 #include "nsTArray.h"
 
 class nsIPresentationRespondingListener;
-class nsString;
 
 namespace mozilla {
 namespace dom {
 
-class PresentationServiceBase : public nsISupports
+template<class T>
+class PresentationServiceBase
 {
 public:
-  NS_DECL_ISUPPORTS
+  PresentationServiceBase() = default;
+
+  already_AddRefed<T>
+  GetSessionInfo(const nsAString& aSessionId, const uint8_t aRole)
+  {
+    MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
+               aRole == nsIPresentationService::ROLE_RECEIVER);
 
-  PresentationServiceBase() = default;
+    RefPtr<T> info;
+    if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
+      return mSessionInfoAtController.Get(aSessionId, getter_AddRefs(info)) ?
+             info.forget() : nullptr;
+    } else {
+      return mSessionInfoAtReceiver.Get(aSessionId, getter_AddRefs(info)) ?
+             info.forget() : nullptr;
+    }
+  }
 
 protected:
   class SessionIdManager final
   {
   public:
     explicit SessionIdManager()
     {
       MOZ_COUNT_CTOR(SessionIdManager);
     }
 
     ~SessionIdManager()
     {
       MOZ_COUNT_DTOR(SessionIdManager);
     }
 
-    nsresult GetWindowId(const nsAString& aSessionId, uint64_t* aWindowId);
+    nsresult GetWindowId(const nsAString& aSessionId, uint64_t* aWindowId)
+    {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      if (mRespondingWindowIds.Get(aSessionId, aWindowId)) {
+        return NS_OK;
+      }
+      return NS_ERROR_NOT_AVAILABLE;
+    }
+
+    nsresult GetSessionIds(uint64_t aWindowId, nsTArray<nsString>& aSessionIds)
+    {
+      MOZ_ASSERT(NS_IsMainThread());
 
-    nsresult GetSessionIds(uint64_t aWindowId, nsTArray<nsString>& aSessionIds);
+      nsTArray<nsString>* sessionIdArray;
+      if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) {
+        return NS_ERROR_INVALID_ARG;
+      }
+
+      aSessionIds.Assign(*sessionIdArray);
+      return NS_OK;
+    }
+
+    void AddSessionId(uint64_t aWindowId, const nsAString& aSessionId)
+    {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      if (NS_WARN_IF(aWindowId == 0)) {
+        return;
+      }
 
-    void AddSessionId(uint64_t aWindowId, const nsAString& aSessionId);
+      nsTArray<nsString>* sessionIdArray;
+      if (!mRespondingSessionIds.Get(aWindowId, &sessionIdArray)) {
+        sessionIdArray = new nsTArray<nsString>();
+        mRespondingSessionIds.Put(aWindowId, sessionIdArray);
+      }
+
+      sessionIdArray->AppendElement(nsString(aSessionId));
+      mRespondingWindowIds.Put(aSessionId, aWindowId);
+    }
+
+    void RemoveSessionId(const nsAString& aSessionId)
+    {
+      MOZ_ASSERT(NS_IsMainThread());
 
-    void RemoveSessionId(const nsAString& aSessionId);
+      uint64_t windowId = 0;
+      if (mRespondingWindowIds.Get(aSessionId, &windowId)) {
+        mRespondingWindowIds.Remove(aSessionId);
+        nsTArray<nsString>* sessionIdArray;
+        if (mRespondingSessionIds.Get(windowId, &sessionIdArray)) {
+          sessionIdArray->RemoveElement(nsString(aSessionId));
+          if (sessionIdArray->IsEmpty()) {
+            mRespondingSessionIds.Remove(windowId);
+          }
+        }
+      }
+    }
 
-    nsresult UpdateWindowId(const nsAString& aSessionId, const uint64_t aWindowId);
+    nsresult UpdateWindowId(const nsAString& aSessionId, const uint64_t aWindowId)
+    {
+      MOZ_ASSERT(NS_IsMainThread());
+
+      RemoveSessionId(aSessionId);
+      AddSessionId(aWindowId, aSessionId);
+      return NS_OK;
+    }
 
     void Clear()
     {
       mRespondingSessionIds.Clear();
       mRespondingWindowIds.Clear();
     }
 
   private:
@@ -65,36 +138,86 @@ protected:
   {
     mRespondingListeners.Clear();
     mControllerSessionIdManager.Clear();
     mReceiverSessionIdManager.Clear();
   }
 
   nsresult GetWindowIdBySessionIdInternal(const nsAString& aSessionId,
                                           uint8_t aRole,
-                                          uint64_t* aWindowId);
+                                          uint64_t* aWindowId)
+  {
+    MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
+               aRole == nsIPresentationService::ROLE_RECEIVER);
+
+    if (NS_WARN_IF(!aWindowId)) {
+      return NS_ERROR_INVALID_POINTER;
+    }
+
+    if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
+      return mControllerSessionIdManager.GetWindowId(aSessionId, aWindowId);
+    }
+
+    return mReceiverSessionIdManager.GetWindowId(aSessionId, aWindowId);
+  }
+
   void AddRespondingSessionId(uint64_t aWindowId,
                               const nsAString& aSessionId,
-                              uint8_t aRole);
+                              uint8_t aRole)
+  {
+    MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
+               aRole == nsIPresentationService::ROLE_RECEIVER);
+
+    if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
+      mControllerSessionIdManager.AddSessionId(aWindowId, aSessionId);
+    } else {
+      mReceiverSessionIdManager.AddSessionId(aWindowId, aSessionId);
+    }
+  }
+
   void RemoveRespondingSessionId(const nsAString& aSessionId,
-                                 uint8_t aRole);
+                                 uint8_t aRole)
+  {
+    MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
+               aRole == nsIPresentationService::ROLE_RECEIVER);
+
+    if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
+      mControllerSessionIdManager.RemoveSessionId(aSessionId);
+    } else {
+      mReceiverSessionIdManager.RemoveSessionId(aSessionId);
+    }
+  }
+
   nsresult UpdateWindowIdBySessionIdInternal(const nsAString& aSessionId,
                                              uint8_t aRole,
-                                             const uint64_t aWindowId);
+                                             const uint64_t aWindowId)
+  {
+    MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
+               aRole == nsIPresentationService::ROLE_RECEIVER);
+
+    if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
+      return mControllerSessionIdManager.UpdateWindowId(aSessionId, aWindowId);
+    }
+
+    return mReceiverSessionIdManager.UpdateWindowId(aSessionId, aWindowId);
+  }
 
   // Store the responding listener based on the window ID of the (in-process or
   // OOP) receiver page.
   nsRefPtrHashtable<nsUint64HashKey, nsIPresentationRespondingListener>
   mRespondingListeners;
 
   // Store the mapping between the window ID of the in-process and OOP page and the ID
   // of the responding session. It's used for both controller and receiver page
   // to retrieve the correspondent session ID. Besides, also keep the mapping
   // between the responding session ID and the window ID to help look up the
   // window ID.
   SessionIdManager mControllerSessionIdManager;
   SessionIdManager mReceiverSessionIdManager;
+
+  nsRefPtrHashtable<nsStringHashKey, T> mSessionInfoAtController;
+  nsRefPtrHashtable<nsStringHashKey, T> mSessionInfoAtReceiver;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PresentationServiceBase_h
--- a/dom/presentation/ipc/PresentationIPCService.cpp
+++ b/dom/presentation/ipc/PresentationIPCService.cpp
@@ -22,19 +22,17 @@ using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace {
 
 PresentationChild* sPresentationChild;
 
 } // anonymous
 
-NS_IMPL_ISUPPORTS_INHERITED(PresentationIPCService,
-                            PresentationServiceBase,
-                            nsIPresentationService)
+NS_IMPL_ISUPPORTS(PresentationIPCService, nsIPresentationService)
 
 PresentationIPCService::PresentationIPCService()
 {
   ContentChild* contentChild = ContentChild::GetSingleton();
   if (NS_WARN_IF(!contentChild)) {
     return;
   }
   sPresentationChild = new PresentationChild(this);
@@ -44,17 +42,18 @@ PresentationIPCService::PresentationIPCS
 
 /* virtual */
 PresentationIPCService::~PresentationIPCService()
 {
   Shutdown();
 
   mAvailabilityListeners.Clear();
   mSessionListeners.Clear();
-  mSessionInfos.Clear();
+  mSessionInfoAtController.Clear();
+  mSessionInfoAtReceiver.Clear();
   sPresentationChild = nullptr;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::StartSession(
                const nsTArray<nsString>& aUrls,
                const nsAString& aSessionId,
                const nsAString& aOrigin,
@@ -85,19 +84,20 @@ PresentationIPCService::StartSession(
 NS_IMETHODIMP
 PresentationIPCService::SendSessionMessage(const nsAString& aSessionId,
                                            uint8_t aRole,
                                            const nsAString& aData)
 {
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(!aData.IsEmpty());
 
-  RefPtr<PresentationContentSessionInfo> info;
+  RefPtr<PresentationContentSessionInfo> info =
+    GetSessionInfo(aSessionId, aRole);
   // data channel session transport is maintained by content process
-  if (mSessionInfos.Get(aSessionId, getter_AddRefs(info))) {
+  if (info) {
     return info->Send(aData);
   }
 
   return SendRequest(nullptr, SendSessionMessageRequest(nsString(aSessionId),
                                                         aRole,
                                                         nsString(aData)));
 }
 
@@ -107,19 +107,20 @@ PresentationIPCService::SendSessionBinar
                                              const nsACString &aData)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aData.IsEmpty());
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
 
-  RefPtr<PresentationContentSessionInfo> info;
+  RefPtr<PresentationContentSessionInfo> info =
+    GetSessionInfo(aSessionId, aRole);
   // data channel session transport is maintained by content process
-  if (mSessionInfos.Get(aSessionId, getter_AddRefs(info))) {
+  if (info) {
     return info->SendBinaryMsg(aData);
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::SendSessionBlob(const nsAString& aSessionId,
@@ -127,19 +128,20 @@ PresentationIPCService::SendSessionBlob(
                                         nsIDOMBlob* aBlob)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
   MOZ_ASSERT(aBlob);
 
-  RefPtr<PresentationContentSessionInfo> info;
+  RefPtr<PresentationContentSessionInfo> info =
+    GetSessionInfo(aSessionId, aRole);
   // data channel session transport is maintained by content process
-  if (mSessionInfos.Get(aSessionId, getter_AddRefs(info))) {
+  if (info) {
     return info->SendBlob(aBlob);
   }
 
   return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::CloseSession(const nsAString& aSessionId,
@@ -150,19 +152,19 @@ PresentationIPCService::CloseSession(con
 
   nsresult rv = SendRequest(nullptr, CloseSessionRequest(nsString(aSessionId),
                                                          aRole,
                                                          aClosedReason));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  RefPtr<PresentationContentSessionInfo> info;
-  // data channel session transport is maintained by content process
-  if (mSessionInfos.Get(aSessionId, getter_AddRefs(info))) {
+  RefPtr<PresentationContentSessionInfo> info =
+    GetSessionInfo(aSessionId, aRole);
+  if (info) {
     return info->Close(NS_OK);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::TerminateSession(const nsAString& aSessionId,
@@ -170,19 +172,19 @@ PresentationIPCService::TerminateSession
 {
   MOZ_ASSERT(!aSessionId.IsEmpty());
 
   nsresult rv = SendRequest(nullptr, TerminateSessionRequest(nsString(aSessionId), aRole));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  RefPtr<PresentationContentSessionInfo> info;
-  // data channel session transport is maintained by content process
-  if (mSessionInfos.Get(aSessionId, getter_AddRefs(info))) {
+  RefPtr<PresentationContentSessionInfo> info =
+    GetSessionInfo(aSessionId, aRole);
+  if (info) {
     return info->Close(NS_OK);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::ReconnectSession(const nsTArray<nsString>& aUrls,
@@ -331,17 +333,22 @@ PresentationIPCService::NotifySessionTra
                                                nsIPresentationSessionTransport* aTransport)
 {
   RefPtr<PresentationContentSessionInfo> info =
     new PresentationContentSessionInfo(aSessionId, aRole, aTransport);
 
   if (NS_WARN_IF(NS_FAILED(info->Init()))) {
     return NS_ERROR_NOT_AVAILABLE;
   }
-  mSessionInfos.Put(aSessionId, info);
+
+  if (aRole == nsIPresentationService::ROLE_CONTROLLER) {
+    mSessionInfoAtController.Put(aSessionId, info);
+  } else {
+    mSessionInfoAtReceiver.Put(aSessionId, info);
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::GetWindowIdBySessionId(const nsAString& aSessionId,
                                                uint8_t aRole,
                                                uint64_t* aWindowId)
 {
@@ -384,17 +391,19 @@ PresentationIPCService::NotifyMessage(co
 }
 
 // Only used for OOP RTCDataChannel session transport case.
 nsresult
 PresentationIPCService::NotifyTransportClosed(const nsAString& aSessionId,
                                               uint8_t aRole,
                                               nsresult aReason)
 {
-  if (NS_WARN_IF(!mSessionInfos.Contains(aSessionId))) {
+  RefPtr<PresentationContentSessionInfo> info =
+    GetSessionInfo(aSessionId, aRole);
+  if (NS_WARN_IF(!info)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   Unused << NS_WARN_IF(!sPresentationChild->SendNotifyTransportClosed(nsString(aSessionId), aRole, aReason));
   return NS_OK;
 }
 
 nsresult
 PresentationIPCService::NotifySessionConnect(uint64_t aWindowId,
@@ -469,18 +478,21 @@ PresentationIPCService::UntrackSessionIn
           window->Close();
         }
       }));
     }
   }
 
   // Remove the OOP responding info (if it has never been used).
   RemoveRespondingSessionId(aSessionId, aRole);
-  if (mSessionInfos.Contains(aSessionId)) {
-    mSessionInfos.Remove(aSessionId);
+
+  if (nsIPresentationService::ROLE_CONTROLLER == aRole) {
+    mSessionInfoAtController.Remove(aSessionId);
+  } else {
+    mSessionInfoAtReceiver.Remove(aSessionId);
   }
 
   return NS_OK;
 }
 
 void
 PresentationIPCService::NotifyPresentationChildDestroyed()
 {
--- a/dom/presentation/ipc/PresentationIPCService.h
+++ b/dom/presentation/ipc/PresentationIPCService.h
@@ -16,21 +16,22 @@ class nsIDocShell;
 
 namespace mozilla {
 namespace dom {
 
 class PresentationIPCRequest;
 class PresentationContentSessionInfo;
 class PresentationResponderLoadingCallback;
 
-class PresentationIPCService final : public nsIPresentationService
-                                   , public PresentationServiceBase
+class PresentationIPCService final
+  : public nsIPresentationService
+  , public PresentationServiceBase<PresentationContentSessionInfo>
 {
 public:
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_ISUPPORTS
   NS_DECL_NSIPRESENTATIONSERVICE
 
   PresentationIPCService();
 
   nsresult NotifyAvailableChange(bool aAvailable);
 
   nsresult NotifySessionStateChange(const nsAString& aSessionId,
                                     uint16_t aState,
@@ -58,16 +59,14 @@ private:
                        const PresentationIPCRequest& aRequest);
 
   nsTObserverArray<nsCOMPtr<nsIPresentationAvailabilityListener> > mAvailabilityListeners;
   nsRefPtrHashtable<nsStringHashKey,
                     nsIPresentationSessionListener> mSessionListeners;
   nsRefPtrHashtable<nsUint64HashKey,
                     nsIPresentationRespondingListener> mRespondingListeners;
   RefPtr<PresentationResponderLoadingCallback> mCallback;
-  nsRefPtrHashtable<nsStringHashKey,
-                    PresentationContentSessionInfo> mSessionInfos;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PresentationIPCService_h
--- a/dom/presentation/moz.build
+++ b/dom/presentation/moz.build
@@ -45,17 +45,16 @@ UNIFIED_SOURCES += [
     'PresentationAvailability.cpp',
     'PresentationCallbacks.cpp',
     'PresentationConnection.cpp',
     'PresentationConnectionList.cpp',
     'PresentationDeviceManager.cpp',
     'PresentationReceiver.cpp',
     'PresentationRequest.cpp',
     'PresentationService.cpp',
-    'PresentationServiceBase.cpp',
     'PresentationSessionInfo.cpp',
     'PresentationSessionRequest.cpp',
     'PresentationTCPSessionTransport.cpp',
     'PresentationTerminateRequest.cpp',
     'PresentationTransportBuilderConstructor.cpp'
 ]
 
 EXTRA_COMPONENTS += [