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 315829 c572919bea3524d38e1a3364a4acba332910b84a
parent 315828 6e6856e101c6e70c5f2f19089719f3e6df2bc3db
child 315830 f8797c70734845bba0e918977e276f6b76e9769e
push id20634
push usercbook@mozilla.com
push dateFri, 30 Sep 2016 10:10:13 +0000
treeherderfx-team@afe79b010d13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1301259
milestone52.0a1
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 += [