Bug 1148307 - Part1 - separate object bruilder from nsIPresentationSessionTransport, r=smaug
☠☠ backed out by 6004772c0cf4 ☠ ☠
authorJunior Hsu <juhsu@mozilla.com>
Thu, 24 Sep 2015 16:16:47 +0800
changeset 316364 17dfb6404d37023c552fdb7065be449a00e53ccc
parent 316363 1258adc301a8a61b1cb401c28144202ba35825ea
child 316365 dfe4cc7062d1954f3ce54a5e330375442766f9bd
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1148307
milestone48.0a1
Bug 1148307 - Part1 - separate object bruilder from nsIPresentationSessionTransport, r=smaug
dom/presentation/PresentationSessionInfo.cpp
dom/presentation/PresentationSessionInfo.h
dom/presentation/PresentationSessionTransport.cpp
dom/presentation/PresentationSessionTransport.h
dom/presentation/PresentationTCPSessionTransport.cpp
dom/presentation/PresentationTCPSessionTransport.h
dom/presentation/interfaces/moz.build
dom/presentation/interfaces/nsIPresentationSessionTransport.idl
dom/presentation/interfaces/nsIPresentationSessionTransportBuilder.idl
dom/presentation/moz.build
dom/presentation/tests/mochitest/PresentationSessionChromeScript.js
dom/presentation/tests/xpcshell/test_presentation_session_transport.js
layout/build/nsLayoutModule.cpp
--- a/dom/presentation/PresentationSessionInfo.cpp
+++ b/dom/presentation/PresentationSessionInfo.cpp
@@ -116,56 +116,56 @@ PresentationNetworkHelper::OnGetWifiIPAd
                                            aIPAddress));
   return NS_OK;
 }
 
 } // anonymous namespace
 
 #endif // MOZ_WIDGET_ANDROID
 
-class PresentationChannelDescription final : public nsIPresentationChannelDescription
+class TCPPresentationChannelDescription final : public nsIPresentationChannelDescription
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPRESENTATIONCHANNELDESCRIPTION
 
-  PresentationChannelDescription(const nsACString& aAddress,
-                                 uint16_t aPort)
+  TCPPresentationChannelDescription(const nsACString& aAddress,
+                                    uint16_t aPort)
     : mAddress(aAddress)
     , mPort(aPort)
   {
   }
 
 private:
-  ~PresentationChannelDescription() {}
+  ~TCPPresentationChannelDescription() {}
 
   nsCString mAddress;
   uint16_t mPort;
 };
 
 } // namespace dom
 } // namespace mozilla
 
-NS_IMPL_ISUPPORTS(PresentationChannelDescription, nsIPresentationChannelDescription)
+NS_IMPL_ISUPPORTS(TCPPresentationChannelDescription, nsIPresentationChannelDescription)
 
 NS_IMETHODIMP
-PresentationChannelDescription::GetType(uint8_t* aRetVal)
+TCPPresentationChannelDescription::GetType(uint8_t* aRetVal)
 {
   if (NS_WARN_IF(!aRetVal)) {
     return NS_ERROR_INVALID_POINTER;
   }
 
   // TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
   // Only support TCP socket for now.
   *aRetVal = nsIPresentationChannelDescription::TYPE_TCP;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PresentationChannelDescription::GetTcpAddress(nsIArray** aRetVal)
+TCPPresentationChannelDescription::GetTcpAddress(nsIArray** aRetVal)
 {
   if (NS_WARN_IF(!aRetVal)) {
     return NS_ERROR_INVALID_POINTER;
   }
 
   nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID);
   if (NS_WARN_IF(!array)) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -184,42 +184,43 @@ PresentationChannelDescription::GetTcpAd
 
   array->AppendElement(address, false);
   array.forget(aRetVal);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PresentationChannelDescription::GetTcpPort(uint16_t* aRetVal)
+TCPPresentationChannelDescription::GetTcpPort(uint16_t* aRetVal)
 {
   if (NS_WARN_IF(!aRetVal)) {
     return NS_ERROR_INVALID_POINTER;
   }
 
   *aRetVal = mPort;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PresentationChannelDescription::GetDataChannelSDP(nsAString& aDataChannelSDP)
+TCPPresentationChannelDescription::GetDataChannelSDP(nsAString& aDataChannelSDP)
 {
   // TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
   // Only support TCP socket for now.
   aDataChannelSDP.Truncate();
   return NS_OK;
 }
 
 /*
  * Implementation of PresentationSessionInfo
  */
 
 NS_IMPL_ISUPPORTS(PresentationSessionInfo,
                   nsIPresentationSessionTransportCallback,
-                  nsIPresentationControlChannelListener);
+                  nsIPresentationControlChannelListener,
+                  nsIPresentationSessionTransportBuilderListener);
 
 /* virtual */ nsresult
 PresentationSessionInfo::Init(nsIPresentationControlChannel* aControlChannel)
 {
   SetControlChannel(aControlChannel);
   return NS_OK;
 }
 
@@ -401,16 +402,41 @@ PresentationSessionInfo::NotifyData(cons
 
   if (NS_WARN_IF(!mListener)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   return mListener->NotifyMessage(mSessionId, aData);
 }
 
+// nsIPresentationSessionTransportBuilderListener
+NS_IMETHODIMP
+PresentationSessionInfo::OnSessionTransport(nsIPresentationSessionTransport* transport)
+{
+  mTransport = transport;
+
+  nsresult rv = mTransport->SetCallback(this);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (mListener) {
+    mTransport->EnableDataNotification();
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationSessionInfo::OnError(nsresult reason)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+
 /*
  * Implementation of PresentationControllingInfo
  *
  * During presentation session establishment, the sender expects the following
  * after trying to establish the control channel: (The order between step 3 and
  * 4 is not guaranteed.)
  * 1. |Init| is called to open a socket |mServerSocket| for data transport
  *    channel.
@@ -565,18 +591,18 @@ PresentationControllingInfo::OnGetAddres
 
   // Prepare and send the offer.
   int32_t port;
   nsresult rv = mServerSocket->GetPort(&port);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  RefPtr<PresentationChannelDescription> description =
-    new PresentationChannelDescription(aAddress, static_cast<uint16_t>(port));
+  RefPtr<TCPPresentationChannelDescription> description =
+    new TCPPresentationChannelDescription(aAddress, static_cast<uint16_t>(port));
   return mControlChannel->SendOffer(description);
 }
 
 // nsIPresentationControlChannelListener
 NS_IMETHODIMP
 PresentationControllingInfo::OnOffer(nsIPresentationChannelDescription* aDescription)
 {
   MOZ_ASSERT(false, "Sender side should not receive offer.");
@@ -639,33 +665,24 @@ PresentationControllingInfo::OnSocketAcc
   int32_t port;
   nsresult rv = aTransport->GetPort(&port);
   if (!NS_WARN_IF(NS_FAILED(rv))) {
     PRES_DEBUG("%s:receive from port[%d]\n",__func__, port);
   }
 
   MOZ_ASSERT(NS_IsMainThread());
 
-  // Initialize |mTransport| and use |this| as the callback.
-  mTransport = do_CreateInstance(PRESENTATION_SESSION_TRANSPORT_CONTRACTID);
-  if (NS_WARN_IF(!mTransport)) {
+  // Initialize session transport builder and use |this| as the callback.
+  nsCOMPtr<nsIPresentationTCPSessionTransportBuilder> builder =
+    do_CreateInstance(PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID);
+  if (NS_WARN_IF(!builder)) {
     return ReplyError(NS_ERROR_DOM_OPERATION_ERR);
   }
 
-  rv = mTransport->InitWithSocketTransport(aTransport, this);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // Enable data notification if the listener has been registered.
-  if (mListener) {
-    return mTransport->EnableDataNotification();
-  }
-
-  return NS_OK;
+  return builder->BuildTCPSenderTransport(aTransport, this);
 }
 
 NS_IMETHODIMP
 PresentationControllingInfo::OnStopListening(nsIServerSocket* aServerSocket,
                                            nsresult aStatus)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -740,61 +757,64 @@ PresentationPresentingInfo::Shutdown(nsr
     mTimer->Cancel();
   }
 
   mLoadingCallback = nullptr;
   mRequesterDescription = nullptr;
   mPromise = nullptr;
 }
 
-nsresult
-PresentationPresentingInfo::InitTransportAndSendAnswer()
+// nsIPresentationSessionTransportBuilderListener
+NS_IMETHODIMP
+PresentationPresentingInfo::OnSessionTransport(nsIPresentationSessionTransport* transport)
 {
-  // Establish a data transport channel |mTransport| to the sender and use
-  // |this| as the callback.
-  mTransport = do_CreateInstance(PRESENTATION_SESSION_TRANSPORT_CONTRACTID);
-  if (NS_WARN_IF(!mTransport)) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  nsresult rv = mTransport->InitWithChannelDescription(mRequesterDescription, this);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  // Enable data notification if the listener has been registered.
-  if (mListener) {
-    rv = mTransport->EnableDataNotification();
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-  }
+  PresentationSessionInfo::OnSessionTransport(transport);
 
   // Prepare and send the answer.
   // TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
   // In the current implementation of |PresentationSessionTransport|,
   // |GetSelfAddress| cannot return the real info when it's initialized via
   // |InitWithChannelDescription|. Yet this deficiency only affects the channel
   // description for the answer, which is not actually checked at requester side.
   nsCOMPtr<nsINetAddr> selfAddr;
-  rv = mTransport->GetSelfAddress(getter_AddRefs(selfAddr));
+  nsresult rv = mTransport->GetSelfAddress(getter_AddRefs(selfAddr));
   NS_WARN_IF(NS_FAILED(rv));
 
   nsCString address;
   uint16_t port = 0;
   if (NS_SUCCEEDED(rv)) {
     selfAddr->GetAddress(address);
     selfAddr->GetPort(&port);
   }
   nsCOMPtr<nsIPresentationChannelDescription> description =
-    new PresentationChannelDescription(address, port);
+    new TCPPresentationChannelDescription(address, port);
 
   return mControlChannel->SendAnswer(description);
 }
 
+NS_IMETHODIMP
+PresentationPresentingInfo::OnError(nsresult reason)
+{
+  return PresentationSessionInfo::OnError(reason);
+}
+
+nsresult
+PresentationPresentingInfo::InitTransportAndSendAnswer()
+{
+  // Establish a data transport channel |mTransport| to the sender and use
+  // |this| as the callback.
+  nsCOMPtr<nsIPresentationTCPSessionTransportBuilder> builder =
+    do_CreateInstance(PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID);
+  if (NS_WARN_IF(!builder)) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  return builder->BuildTCPReceiverTransport(mRequesterDescription, this);
+}
+
 nsresult
 PresentationPresentingInfo::UntrackFromService()
 {
   // Remove the OOP responding info (if it has never been used).
   if (mContentParent) {
     NS_WARN_IF(!static_cast<ContentParent*>(mContentParent.get())->SendNotifyPresentationReceiverCleanUp(mSessionId));
   }
 
--- a/dom/presentation/PresentationSessionInfo.h
+++ b/dom/presentation/PresentationSessionInfo.h
@@ -13,30 +13,33 @@
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIPresentationControlChannel.h"
 #include "nsIPresentationDevice.h"
 #include "nsIPresentationListener.h"
 #include "nsIPresentationService.h"
 #include "nsIPresentationSessionTransport.h"
+#include "nsIPresentationSessionTransportBuilder.h"
 #include "nsIServerSocket.h"
 #include "nsITimer.h"
 #include "nsString.h"
 #include "PresentationCallbacks.h"
 
 namespace mozilla {
 namespace dom {
 
 class PresentationSessionInfo : public nsIPresentationSessionTransportCallback
                               , public nsIPresentationControlChannelListener
+                              , public nsIPresentationSessionTransportBuilderListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTCALLBACK
+  NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTBUILDERLISTENER
 
   PresentationSessionInfo(const nsAString& aUrl,
                           const nsAString& aSessionId,
                           nsIPresentationServiceCallback* aCallback)
     : mUrl(aUrl)
     , mSessionId(aSessionId)
     , mIsResponderReady(false)
     , mIsTransportReady(false)
@@ -179,16 +182,17 @@ private:
 // Session info with presenting browsing context (receiver side) behaviors.
 class PresentationPresentingInfo final : public PresentationSessionInfo
                                        , public PromiseNativeHandler
                                        , public nsITimerCallback
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIPRESENTATIONCONTROLCHANNELLISTENER
+  NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTBUILDERLISTENER
   NS_DECL_NSITIMERCALLBACK
 
   PresentationPresentingInfo(const nsAString& aUrl,
                              const nsAString& aSessionId,
                              nsIPresentationDevice* aDevice)
     : PresentationSessionInfo(aUrl, aSessionId, nullptr)
   {
     MOZ_ASSERT(aDevice);
rename from dom/presentation/PresentationSessionTransport.cpp
rename to dom/presentation/PresentationTCPSessionTransport.cpp
--- a/dom/presentation/PresentationSessionTransport.cpp
+++ b/dom/presentation/PresentationTCPSessionTransport.cpp
@@ -11,40 +11,41 @@
 #include "nsIMutableArray.h"
 #include "nsIOutputStream.h"
 #include "nsIPresentationControlChannel.h"
 #include "nsIScriptableInputStream.h"
 #include "nsISocketTransport.h"
 #include "nsISocketTransportService.h"
 #include "nsISupportsPrimitives.h"
 #include "nsNetUtil.h"
+#include "nsQueryObject.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "PresentationLog.h"
-#include "PresentationSessionTransport.h"
+#include "PresentationTCPSessionTransport.h"
 
 #define BUFFER_SIZE 65536
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 class CopierCallbacks final : public nsIRequestObserver
 {
 public:
-  explicit CopierCallbacks(PresentationSessionTransport* aTransport)
+  explicit CopierCallbacks(PresentationTCPSessionTransport* aTransport)
     : mOwner(aTransport)
   {}
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
 private:
   ~CopierCallbacks() {}
 
-  RefPtr<PresentationSessionTransport> mOwner;
+  RefPtr<PresentationTCPSessionTransport> mOwner;
 };
 
 NS_IMPL_ISUPPORTS(CopierCallbacks, nsIRequestObserver)
 
 NS_IMETHODIMP
 CopierCallbacks::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
 {
   return NS_OK;
@@ -52,86 +53,95 @@ CopierCallbacks::OnStartRequest(nsIReque
 
 NS_IMETHODIMP
 CopierCallbacks::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsresult aStatus)
 {
   mOwner->NotifyCopyComplete(aStatus);
   return NS_OK;
 }
 
-NS_IMPL_CYCLE_COLLECTION(PresentationSessionTransport, mTransport,
+NS_IMPL_CYCLE_COLLECTION(PresentationTCPSessionTransport, mTransport,
                          mSocketInputStream, mSocketOutputStream,
                          mInputStreamPump, mInputStreamScriptable,
                          mMultiplexStream, mMultiplexStreamCopier, mCallback)
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(PresentationSessionTransport)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationSessionTransport)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(PresentationTCPSessionTransport)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(PresentationTCPSessionTransport)
 
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationSessionTransport)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PresentationTCPSessionTransport)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPresentationSessionTransport)
   NS_INTERFACE_MAP_ENTRY(nsIPresentationSessionTransport)
   NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
+  NS_INTERFACE_MAP_ENTRY(nsIPresentationTCPSessionTransportBuilder)
   NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
   NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
   NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
 NS_INTERFACE_MAP_END
 
-PresentationSessionTransport::PresentationSessionTransport()
-  : mReadyState(CLOSED)
+PresentationTCPSessionTransport::PresentationTCPSessionTransport()
+  : mReadyState(ReadyState::CLOSED)
   , mAsyncCopierActive(false)
   , mCloseStatus(NS_OK)
   , mDataNotificationEnabled(false)
 {
 }
 
-PresentationSessionTransport::~PresentationSessionTransport()
+PresentationTCPSessionTransport::~PresentationTCPSessionTransport()
 {
 }
 
 NS_IMETHODIMP
-PresentationSessionTransport::InitWithSocketTransport(nsISocketTransport* aTransport,
-                                                      nsIPresentationSessionTransportCallback* aCallback)
+PresentationTCPSessionTransport::BuildTCPSenderTransport(nsISocketTransport* aTransport,
+                                                         nsIPresentationSessionTransportBuilderListener* aListener)
 {
-  if (NS_WARN_IF(!aCallback)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-  mCallback = aCallback;
-
   if (NS_WARN_IF(!aTransport)) {
     return NS_ERROR_INVALID_ARG;
   }
   mTransport = aTransport;
 
+  if (NS_WARN_IF(!aListener)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  mListener = aListener;
+
   nsresult rv = CreateStream();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  SetReadyState(OPEN);
+  SetReadyState(ReadyState::OPEN);
 
   if (IsReadyToNotifyData()) {
     return CreateInputStreamPump();
   }
 
-  return NS_OK;
+  mType = nsIPresentationSessionTransportBuilder::TYPE_SENDER;
+
+  nsCOMPtr<nsIPresentationSessionTransport> sessionTransport = do_QueryObject(this);
+  nsCOMPtr<nsIRunnable> runnable =
+    NS_NewRunnableMethodWithArgs
+      <nsIPresentationSessionTransport*>(mListener,
+                                         &nsIPresentationSessionTransportBuilderListener::OnSessionTransport,
+                                         sessionTransport);
+  return NS_DispatchToCurrentThread(runnable);
 }
 
 NS_IMETHODIMP
-PresentationSessionTransport::InitWithChannelDescription(nsIPresentationChannelDescription* aDescription,
-                                                         nsIPresentationSessionTransportCallback* aCallback)
+PresentationTCPSessionTransport::BuildTCPReceiverTransport(nsIPresentationChannelDescription* aDescription,
+                                                           nsIPresentationSessionTransportBuilderListener* aListener)
 {
-  if (NS_WARN_IF(!aCallback)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-  mCallback = aCallback;
-
   if (NS_WARN_IF(!aDescription)) {
     return NS_ERROR_INVALID_ARG;
   }
 
+  if (NS_WARN_IF(!aListener)) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  mListener = aListener;
+
   uint16_t serverPort;
   nsresult rv = aDescription->GetTcpPort(&serverPort);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   nsCOMPtr<nsIArray> serverHosts;
   rv = aDescription->GetTcpAddress(getter_AddRefs(serverHosts));
@@ -152,17 +162,17 @@ PresentationSessionTransport::InitWithCh
   nsAutoCString serverHost;
   supportStr->GetData(serverHost);
   if (serverHost.IsEmpty()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   PRES_DEBUG("%s:ServerHost[%s],ServerPort[%d]\n", __func__, serverHost.get(), serverPort);
 
-  SetReadyState(CONNECTING);
+  SetReadyState(ReadyState::CONNECTING);
 
   nsCOMPtr<nsISocketTransportService> sts =
     do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID);
   if (NS_WARN_IF(!sts)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   rv = sts->CreateTransport(nullptr, 0, serverHost, serverPort, nullptr,
                             getter_AddRefs(mTransport));
@@ -175,21 +185,29 @@ PresentationSessionTransport::InitWithCh
 
   mTransport->SetEventSink(this, mainThread);
 
   rv = CreateStream();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  return NS_OK;
+  mType = nsIPresentationSessionTransportBuilder::TYPE_RECEIVER;
+
+  nsCOMPtr<nsIPresentationSessionTransport> sessionTransport = do_QueryObject(this);
+  nsCOMPtr<nsIRunnable> runnable =
+    NS_NewRunnableMethodWithArgs
+      <nsIPresentationSessionTransport*>(mListener,
+                                         &nsIPresentationSessionTransportBuilderListener::OnSessionTransport,
+                                         sessionTransport);
+  return NS_DispatchToCurrentThread(runnable);
 }
 
 nsresult
-PresentationSessionTransport::CreateStream()
+PresentationTCPSessionTransport::CreateStream()
 {
   nsresult rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(mSocketInputStream));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   rv = mTransport->OpenOutputStream(nsITransport::OPEN_UNBUFFERED, 0, 0, getter_AddRefs(mSocketOutputStream));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
@@ -247,17 +265,17 @@ PresentationSessionTransport::CreateStre
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 nsresult
-PresentationSessionTransport::CreateInputStreamPump()
+PresentationTCPSessionTransport::CreateInputStreamPump()
 {
   nsresult rv;
   mInputStreamPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   rv = mInputStreamPump->Init(mSocketInputStream, -1, -1, 0, 0, false);
@@ -269,17 +287,17 @@ PresentationSessionTransport::CreateInpu
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PresentationSessionTransport::EnableDataNotification()
+PresentationTCPSessionTransport::EnableDataNotification()
 {
   if (NS_WARN_IF(!mCallback)) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   if (mDataNotificationEnabled) {
     return NS_OK;
   }
@@ -288,178 +306,196 @@ PresentationSessionTransport::EnableData
 
   if (IsReadyToNotifyData()) {
     return CreateInputStreamPump();
   }
 
   return NS_OK;
 }
 
+// nsIPresentationSessionTransportBuilderListener
 NS_IMETHODIMP
-PresentationSessionTransport::GetSelfAddress(nsINetAddr** aSelfAddress)
+PresentationTCPSessionTransport::GetCallback(nsIPresentationSessionTransportCallback** aCallback)
+{
+  nsCOMPtr<nsIPresentationSessionTransportCallback> callback = mCallback;
+  callback.forget(aCallback);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationTCPSessionTransport::SetCallback(nsIPresentationSessionTransportCallback* aCallback)
+{
+  mCallback = aCallback;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationTCPSessionTransport::GetSelfAddress(nsINetAddr** aSelfAddress)
 {
   if (NS_WARN_IF(!mTransport)) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   return mTransport->GetScriptableSelfAddr(aSelfAddress);
 }
 
 void
-PresentationSessionTransport::EnsureCopying()
+PresentationTCPSessionTransport::EnsureCopying()
 {
   if (mAsyncCopierActive) {
     return;
   }
 
   mAsyncCopierActive = true;
   RefPtr<CopierCallbacks> callbacks = new CopierCallbacks(this);
   NS_WARN_IF(NS_FAILED(mMultiplexStreamCopier->AsyncCopy(callbacks, nullptr)));
 }
 
 void
-PresentationSessionTransport::NotifyCopyComplete(nsresult aStatus)
+PresentationTCPSessionTransport::NotifyCopyComplete(nsresult aStatus)
 {
   mAsyncCopierActive = false;
   mMultiplexStream->RemoveStream(0);
   if (NS_WARN_IF(NS_FAILED(aStatus))) {
-    if (mReadyState != CLOSED) {
+    if (mReadyState != ReadyState::CLOSED) {
       mCloseStatus = aStatus;
-      SetReadyState(CLOSED);
+      SetReadyState(ReadyState::CLOSED);
     }
     return;
   }
 
   uint32_t count;
   nsresult rv = mMultiplexStream->GetCount(&count);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
 
   if (count) {
     EnsureCopying();
     return;
   }
 
-  if (mReadyState == CLOSING) {
+  if (mReadyState == ReadyState::CLOSING) {
     mSocketOutputStream->Close();
     mCloseStatus = NS_OK;
-    SetReadyState(CLOSED);
+    SetReadyState(ReadyState::CLOSED);
   }
 }
 
 NS_IMETHODIMP
-PresentationSessionTransport::Send(nsIInputStream* aData)
+PresentationTCPSessionTransport::Send(nsIInputStream* aData)
 {
-  if (NS_WARN_IF(mReadyState != OPEN)) {
+  if (NS_WARN_IF(mReadyState != ReadyState::OPEN)) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   mMultiplexStream->AppendStream(aData);
 
   EnsureCopying();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PresentationSessionTransport::Close(nsresult aReason)
+PresentationTCPSessionTransport::Close(nsresult aReason)
 {
   PRES_DEBUG("%s:reason[%x]\n", __func__, aReason);
 
-  if (mReadyState == CLOSED || mReadyState == CLOSING) {
+  if (mReadyState == ReadyState::CLOSED || mReadyState == ReadyState::CLOSING) {
     return NS_OK;
   }
 
   mCloseStatus = aReason;
-  SetReadyState(CLOSING);
+  SetReadyState(ReadyState::CLOSING);
 
   uint32_t count = 0;
   mMultiplexStream->GetCount(&count);
   if (!count) {
     mSocketOutputStream->Close();
   }
 
   mSocketInputStream->Close();
   mDataNotificationEnabled = false;
 
+  mListener = nullptr;
+
   return NS_OK;
 }
 
 void
-PresentationSessionTransport::SetReadyState(ReadyState aReadyState)
+PresentationTCPSessionTransport::SetReadyState(ReadyState aReadyState)
 {
   mReadyState = aReadyState;
 
-  if (mReadyState == OPEN && mCallback) {
+  if (mReadyState == ReadyState::OPEN && mCallback) {
     // Notify the transport channel is ready.
     NS_WARN_IF(NS_FAILED(mCallback->NotifyTransportReady()));
-  } else if (mReadyState == CLOSED && mCallback) {
+  } else if (mReadyState == ReadyState::CLOSED && mCallback) {
     // Notify the transport channel has been shut down.
     NS_WARN_IF(NS_FAILED(mCallback->NotifyTransportClosed(mCloseStatus)));
     mCallback = nullptr;
   }
 }
 
 // nsITransportEventSink
 NS_IMETHODIMP
-PresentationSessionTransport::OnTransportStatus(nsITransport* aTransport,
-                                                nsresult aStatus,
-                                                int64_t aProgress,
-                                                int64_t aProgressMax)
+PresentationTCPSessionTransport::OnTransportStatus(nsITransport* aTransport,
+                                                   nsresult aStatus,
+                                                   int64_t aProgress,
+                                                   int64_t aProgressMax)
 {
   PRES_DEBUG("%s:aStatus[%x]\n", __func__, aStatus);
 
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aStatus != NS_NET_STATUS_CONNECTED_TO) {
     return NS_OK;
   }
 
-  SetReadyState(OPEN);
+  SetReadyState(ReadyState::OPEN);
 
   if (IsReadyToNotifyData()) {
     return CreateInputStreamPump();
   }
 
   return NS_OK;
 }
 
 // nsIInputStreamCallback
 NS_IMETHODIMP
-PresentationSessionTransport::OnInputStreamReady(nsIAsyncInputStream* aStream)
+PresentationTCPSessionTransport::OnInputStreamReady(nsIAsyncInputStream* aStream)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Only used for detecting if the connection was refused.
   uint64_t dummy;
   nsresult rv = aStream->Available(&dummy);
   if (NS_WARN_IF(NS_FAILED(rv))) {
-    if (mReadyState != CLOSED) {
+    if (mReadyState != ReadyState::CLOSED) {
       mCloseStatus = NS_ERROR_CONNECTION_REFUSED;
-      SetReadyState(CLOSED);
+      SetReadyState(ReadyState::CLOSED);
     }
   }
 
   return NS_OK;
 }
 
 // nsIRequestObserver
 NS_IMETHODIMP
-PresentationSessionTransport::OnStartRequest(nsIRequest* aRequest,
-                                             nsISupports* aContext)
+PresentationTCPSessionTransport::OnStartRequest(nsIRequest* aRequest,
+                                                nsISupports* aContext)
 {
   // Do nothing.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PresentationSessionTransport::OnStopRequest(nsIRequest* aRequest,
-                                            nsISupports* aContext,
-                                            nsresult aStatusCode)
+PresentationTCPSessionTransport::OnStopRequest(nsIRequest* aRequest,
+                                               nsISupports* aContext,
+                                               nsresult aStatusCode)
 {
   PRES_DEBUG("%s:aStatusCode[%x]\n", __func__, aStatusCode);
 
   MOZ_ASSERT(NS_IsMainThread());
 
   uint32_t count;
   nsresult rv = mMultiplexStream->GetCount(&count);
   if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -472,30 +508,30 @@ PresentationSessionTransport::OnStopRequ
     // If we have some buffered output still, and status is not an error, the
     // other side has done a half-close, but we don't want to be in the close
     // state until we are done sending everything that was buffered. We also
     // don't want to call |NotifyTransportClosed| yet.
     return NS_OK;
   }
 
   // We call this even if there is no error.
-  if (mReadyState != CLOSED) {
+  if (mReadyState != ReadyState::CLOSED) {
     mCloseStatus = aStatusCode;
-    SetReadyState(CLOSED);
+    SetReadyState(ReadyState::CLOSED);
   }
   return NS_OK;
 }
 
 // nsIStreamListener
 NS_IMETHODIMP
-PresentationSessionTransport::OnDataAvailable(nsIRequest* aRequest,
-                                              nsISupports* aContext,
-                                              nsIInputStream* aStream,
-                                              uint64_t aOffset,
-                                              uint32_t aCount)
+PresentationTCPSessionTransport::OnDataAvailable(nsIRequest* aRequest,
+                                                 nsISupports* aContext,
+                                                 nsIInputStream* aStream,
+                                                 uint64_t aOffset,
+                                                 uint32_t aCount)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (NS_WARN_IF(!mCallback)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsCString data;
rename from dom/presentation/PresentationSessionTransport.h
rename to dom/presentation/PresentationTCPSessionTransport.h
--- a/dom/presentation/PresentationSessionTransport.h
+++ b/dom/presentation/PresentationTCPSessionTransport.h
@@ -6,16 +6,17 @@
 
 #ifndef mozilla_dom_PresentationSessionTransport_h
 #define mozilla_dom_PresentationSessionTransport_h
 
 #include "mozilla/RefPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIAsyncInputStream.h"
 #include "nsIPresentationSessionTransport.h"
+#include "nsIPresentationSessionTransportBuilder.h"
 #include "nsIStreamListener.h"
 #include "nsISupportsImpl.h"
 #include "nsITransport.h"
 
 class nsISocketTransport;
 class nsIInputStreamPump;
 class nsIScriptableInputStream;
 class nsIMultiplexInputStream;
@@ -33,76 +34,82 @@ namespace dom {
  * |PresentationControllingInfo| (sender side) or |PresentationPresentingInfo|
  * (receiver side) in PresentationSessionInfo.cpp.
  *
  * TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
  * The implementation over the TCP channel is primarily used for the early stage
  * of Presentation API (without SSL) and should be migrated to DataChannel with
  * full support soon.
  */
-class PresentationSessionTransport final : public nsIPresentationSessionTransport
-                                         , public nsITransportEventSink
-                                         , public nsIInputStreamCallback
-                                         , public nsIStreamListener
+class PresentationTCPSessionTransport final : public nsIPresentationSessionTransport
+                                            , public nsIPresentationTCPSessionTransportBuilder
+                                            , public nsITransportEventSink
+                                            , public nsIInputStreamCallback
+                                            , public nsIStreamListener
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PresentationSessionTransport,
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(PresentationTCPSessionTransport,
                                            nsIPresentationSessionTransport)
 
   NS_DECL_NSIPRESENTATIONSESSIONTRANSPORT
+  NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTBUILDER
+  NS_DECL_NSIPRESENTATIONTCPSESSIONTRANSPORTBUILDER
   NS_DECL_NSITRANSPORTEVENTSINK
   NS_DECL_NSIINPUTSTREAMCALLBACK
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
 
-  PresentationSessionTransport();
+  PresentationTCPSessionTransport();
 
   void NotifyCopyComplete(nsresult aStatus);
 
 private:
-  ~PresentationSessionTransport();
+  ~PresentationTCPSessionTransport();
 
   nsresult CreateStream();
 
   nsresult CreateInputStreamPump();
 
   void EnsureCopying();
 
-  enum ReadyState {
+  enum class ReadyState {
     CONNECTING,
     OPEN,
     CLOSING,
     CLOSED
   };
 
   void SetReadyState(ReadyState aReadyState);
 
   bool IsReadyToNotifyData()
   {
-    return mDataNotificationEnabled && mReadyState == OPEN;
+    return mDataNotificationEnabled && mReadyState == ReadyState::OPEN;
   }
 
   ReadyState mReadyState;
   bool mAsyncCopierActive;
   nsresult mCloseStatus;
   bool mDataNotificationEnabled;
 
+  uint8_t mType = 0;
+
   // Raw socket streams
   nsCOMPtr<nsISocketTransport> mTransport;
   nsCOMPtr<nsIInputStream> mSocketInputStream;
   nsCOMPtr<nsIOutputStream> mSocketOutputStream;
 
   // Input stream machinery
   nsCOMPtr<nsIInputStreamPump> mInputStreamPump;
   nsCOMPtr<nsIScriptableInputStream> mInputStreamScriptable;
 
   // Output stream machinery
   nsCOMPtr<nsIMultiplexInputStream> mMultiplexStream;
   nsCOMPtr<nsIAsyncStreamCopier> mMultiplexStreamCopier;
 
   nsCOMPtr<nsIPresentationSessionTransportCallback> mCallback;
+  nsCOMPtr<nsIPresentationSessionTransportBuilderListener> mListener;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_PresentationSessionTransport_h
--- a/dom/presentation/interfaces/moz.build
+++ b/dom/presentation/interfaces/moz.build
@@ -10,16 +10,17 @@ XPIDL_SOURCES += [
     'nsIPresentationDeviceManager.idl',
     'nsIPresentationDevicePrompt.idl',
     'nsIPresentationDeviceProvider.idl',
     'nsIPresentationListener.idl',
     'nsIPresentationRequestUIGlue.idl',
     'nsIPresentationService.idl',
     'nsIPresentationSessionRequest.idl',
     'nsIPresentationSessionTransport.idl',
+    'nsIPresentationSessionTransportBuilder.idl',
     'nsITCPPresentationServer.idl',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     XPIDL_SOURCES += [
         'nsIPresentationNetworkHelper.idl',
     ]
 
--- a/dom/presentation/interfaces/nsIPresentationSessionTransport.idl
+++ b/dom/presentation/interfaces/nsIPresentationSessionTransport.idl
@@ -1,64 +1,49 @@
 /* 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 "nsISupports.idl"
 
 interface nsIInputStream;
 interface nsINetAddr;
-interface nsIPresentationChannelDescription;
-interface nsISocketTransport;
 
 %{C++
-#define PRESENTATION_SESSION_TRANSPORT_CONTRACTID \
-  "@mozilla.org/presentation/presentationsessiontransport;1"
+#define PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID \
+  "@mozilla.org/presentation/presentationtcpsessiontransport;1"
 %}
 
 /*
  * The callback for session transport events.
  */
 [scriptable, uuid(9f158786-41a6-4a10-b29b-9497f25d4b67)]
 interface nsIPresentationSessionTransportCallback : nsISupports
 {
   void notifyTransportReady();
   void notifyTransportClosed(in nsresult reason);
   void notifyData(in ACString data);
 };
 
 /*
  * App-to-App transport channel for the presentation session.
  */
-[scriptable, uuid(b6a416cf-03ae-4e74-9cda-88828e8ff418)]
+[scriptable, uuid(7af8556e-e37b-4ca1-a5dd-029567172863)]
 interface nsIPresentationSessionTransport : nsISupports
 {
-  readonly attribute nsINetAddr selfAddress;
+  // Should be set once the underlying session transport is built
+  attribute nsIPresentationSessionTransportCallback callback;
 
-  /*
-   * Initialize the transport channel with an existent socket transport. (This
-   * is primarily used at the sender side.)
-   * @param transport The socket transport.
-   * @param callback The callback for followup notifications.
-   */
-  void initWithSocketTransport(in nsISocketTransport transport,
-                               in nsIPresentationSessionTransportCallback callback);
-
-  /*
-   * Initialize the transport channel with the channel description. (This is
-   * primarily used at the receiver side.)
-   * @param description The channel description.
-   * @param callback The callback for followup notifications.
-   */
-  void initWithChannelDescription(in nsIPresentationChannelDescription description,
-                                  in nsIPresentationSessionTransportCallback callback);
+  // valid for TCP session transport
+  readonly attribute nsINetAddr selfAddress;
 
   /*
    * Enable the notification for incoming data. |notifyData| of
    * |nsIPresentationSessionTransportCallback| can start getting invoked.
+   * Should set callback before |enableDataNotification| is called.
    */
   void enableDataNotification();
 
   /*
    * Send message to the remote endpoint.
    * @param data The message to send.
    */
   void send(in nsIInputStream data);
new file mode 100644
--- /dev/null
+++ b/dom/presentation/interfaces/nsIPresentationSessionTransportBuilder.idl
@@ -0,0 +1,62 @@
+/* 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 "nsISupports.idl"
+
+interface nsIPresentationChannelDescription;
+interface nsISocketTransport;
+interface nsIDOMWindow;
+interface nsIPresentationControlChannel;
+interface nsIPresentationSessionTransport;
+
+[scriptable, uuid(673f6de1-e253-41b8-9be8-b7ff161fa8dc)]
+interface nsIPresentationSessionTransportBuilderListener : nsISupports
+{
+  // Should set |transport.callback| in |onSessionTransport|.
+  void onSessionTransport(in nsIPresentationSessionTransport transport);
+
+  void onError(in nsresult reason);
+};
+
+[scriptable, uuid(2fdbe67d-80f9-48dc-8237-5bef8fa19801)]
+interface nsIPresentationSessionTransportBuilder : nsISupports
+{
+  const unsigned short TYPE_SENDER = 1;
+  const unsigned short TYPE_RECEIVER = 2;
+};
+
+/**
+ * Builder for TCP session transport
+ */
+[scriptable, uuid(cde36d6e-f471-4262-a70d-f932a26b21d9)]
+interface nsIPresentationTCPSessionTransportBuilder : nsIPresentationSessionTransportBuilder
+{
+  /**
+   * The following creation functions will trigger |listener.onSessionTransport|
+   * if the session transport is successfully built, |listener.onError| if some
+   * error occurs during building session transport.
+   */
+  void buildTCPSenderTransport(in nsISocketTransport aTransport,
+                               in nsIPresentationSessionTransportBuilderListener aListener);
+
+  void buildTCPReceiverTransport(in nsIPresentationChannelDescription aDescription,
+                                 in nsIPresentationSessionTransportBuilderListener aListener);
+};
+
+/**
+ * Builder for WebRTC data channel session transport
+ */
+[scriptable, uuid(8131c4e0-3a8c-4bc1-a92a-8431473d2fe8)]
+interface nsIPresentationDataChannelSessionTransportBuilder : nsIPresentationSessionTransportBuilder
+{
+  /**
+   * The following creation function will trigger |listener.onSessionTransport|
+   * if the session transport is successfully built, |listener.onError| if some
+   * error occurs during creating session transport.
+   */
+  void buildDataChannelTransport(in uint8_t aType,
+                                 in nsIDOMWindow aWindow,
+                                 in nsIPresentationControlChannel aControlChannel,
+                                 in nsIPresentationSessionTransportBuilderListener aListener);
+};
--- a/dom/presentation/moz.build
+++ b/dom/presentation/moz.build
@@ -17,34 +17,34 @@ EXPORTS.mozilla.dom += [
     'PresentationAvailability.h',
     'PresentationCallbacks.h',
     'PresentationConnection.h',
     'PresentationDeviceManager.h',
     'PresentationReceiver.h',
     'PresentationRequest.h',
     'PresentationService.h',
     'PresentationSessionInfo.h',
-    'PresentationSessionTransport.h',
+    'PresentationTCPSessionTransport.h',
 ]
 
 UNIFIED_SOURCES += [
     'ipc/PresentationChild.cpp',
     'ipc/PresentationIPCService.cpp',
     'ipc/PresentationParent.cpp',
     'Presentation.cpp',
     'PresentationAvailability.cpp',
     'PresentationCallbacks.cpp',
     'PresentationConnection.cpp',
     'PresentationDeviceManager.cpp',
     'PresentationReceiver.cpp',
     'PresentationRequest.cpp',
     'PresentationService.cpp',
     'PresentationSessionInfo.cpp',
     'PresentationSessionRequest.cpp',
-    'PresentationSessionTransport.cpp',
+    'PresentationTCPSessionTransport.cpp',
 ]
 
 EXTRA_COMPONENTS += [
     'PresentationDeviceInfoManager.js',
     'PresentationDeviceInfoManager.manifest',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
--- a/dom/presentation/tests/mochitest/PresentationSessionChromeScript.js
+++ b/dom/presentation/tests/mochitest/PresentationSessionChromeScript.js
@@ -193,47 +193,57 @@ const mockedDevicePrompt = {
   },
   simulateCancel: function() {
     this._request.cancel();
   }
 };
 
 const mockedSessionTransport = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransport,
+                                         Ci.nsIPresentationTCPSessionTransportBuilder,
                                          Ci.nsIFactory]),
   createInstance: function(aOuter, aIID) {
     if (aOuter) {
       throw Components.results.NS_ERROR_NO_AGGREGATION;
     }
     return this.QueryInterface(aIID);
   },
   set callback(callback) {
     this._callback = callback;
   },
   get callback() {
     return this._callback;
   },
   get selfAddress() {
     return this._selfAddress;
   },
-  initWithSocketTransport: function(transport, callback) {
+  buildTCPSenderTransport: function(transport, listener) {
     sendAsyncMessage('data-transport-initialized');
-    this._callback = callback;
+    this._listener = listener;
+    this._type = Ci.nsIPresentationSessionTransportBuilder.TYPE_SENDER;
+
+    this._listener.onSessionTransport(this);
+    this._listener = null;
+
     this.simulateTransportReady();
   },
-  initWithChannelDescription: function(description, callback) {
-    this._callback = callback;
+  buildTCPReceiverTransport: function(description, listener) {
+    this._listener = listener;
+    this._type = Ci.nsIPresentationSessionTransportBuilder.TYPE_RECEIVER;
 
     var addresses = description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpAddress;
     this._selfAddress = {
       QueryInterface: XPCOMUtils.generateQI([Ci.nsINetAddr]),
       address: (addresses.length > 0) ?
                 addresses.queryElementAt(0, Ci.nsISupportsCString).data : "",
       port: description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpPort,
     };
+
+    this._listener.onSessionTransport(this);
+    this._listener = null;
   },
   enableDataNotification: function() {
     sendAsyncMessage('data-transport-notification-enabled');
   },
   send: function(data) {
     var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
                        createInstance(Ci.nsIBinaryInputStream);
     binaryStream.setInputStream(data);
@@ -297,17 +307,17 @@ const uuidGenerator = Cc["@mozilla.org/u
                       .getService(Ci.nsIUUIDGenerator);
 const originalFactoryData = [];
 originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation-device/prompt;1",
                                                uuidGenerator.generateUUID(),
                                                mockedDevicePrompt));
 originalFactoryData.push(registerMockedFactory("@mozilla.org/network/server-socket;1",
                                                uuidGenerator.generateUUID(),
                                                mockedServerSocket));
-originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/presentationsessiontransport;1",
+originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/presentationtcpsessiontransport;1",
                                                uuidGenerator.generateUUID(),
                                                mockedSessionTransport));
 originalFactoryData.push(registerMockedFactory("@mozilla.org/network/manager;1",
                                                uuidGenerator.generateUUID(),
                                                mockedNetworkManager));
 originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/requestuiglue;1",
                                                uuidGenerator.generateUUID(),
                                                mockedRequestUIGlue));
--- a/dom/presentation/tests/xpcshell/test_presentation_session_transport.js
+++ b/dom/presentation/tests/xpcshell/test_presentation_session_transport.js
@@ -11,16 +11,19 @@ const ServerSocket = CC("@mozilla.org/ne
 
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 Cu.import('resource://gre/modules/Services.jsm');
 
 var testServer = null;
 var clientTransport = null;
 var serverTransport = null;
 
+var clientBuilder = null;
+var serverBuilder = null;
+
 const clientMessage = "Client Message";
 const serverMessage = "Server Message";
 
 const address = Cc["@mozilla.org/supports-cstring;1"]
                   .createInstance(Ci.nsISupportsCString);
 address.data = "127.0.0.1";
 const addresses = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
 addresses.appendElement(address, false);
@@ -79,46 +82,72 @@ const serverCallback = {
     }
   },
   notifyData: function(aData) {
     Assert.equal(aData, clientMessage, "Server transport receives data.");
     run_next_test();
   },
 };
 
+const clientListener = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransportBuilderListener]),
+  onSessionTransport(aTransport) {
+    Assert.ok(true, "Client Transport is built.");
+    clientTransport = aTransport;
+    clientTransport.callback = clientCallback;
+
+    if (serverTransport) {
+      run_next_test();
+    }
+  }
+}
+
+const serverListener = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransportBuilderListener]),
+  onSessionTransport(aTransport) {
+    Assert.ok(true, "Server Transport is built.");
+    serverTransport = aTransport;
+    serverTransport.callback = serverCallback;
+    serverTransport.enableDataNotification();
+
+    if (clientTransport) {
+      run_next_test();
+    }
+  }
+}
+
 function TestServer() {
   this.serverSocket = ServerSocket(-1, true, -1);
   this.serverSocket.asyncListen(this)
 }
 
 TestServer.prototype = {
   onSocketAccepted: function(aSocket, aTransport) {
     print("Test server gets a client connection.");
-    serverTransport = Cc["@mozilla.org/presentation/presentationsessiontransport;1"]
-                        .createInstance(Ci.nsIPresentationSessionTransport);
-    serverTransport.initWithSocketTransport(aTransport, serverCallback);
-    serverTransport.enableDataNotification();
+    serverBuilder = Cc["@mozilla.org/presentation/presentationtcpsessiontransport;1"]
+                      .createInstance(Ci.nsIPresentationTCPSessionTransportBuilder);
+    serverBuilder.buildTCPSenderTransport(aTransport, serverListener);
   },
   onStopListening: function(aSocket) {
     print("Test server stops listening.");
   },
   close: function() {
     if (this.serverSocket) {
       this.serverSocket.close();
       this.serverSocket = null;
     }
   }
 };
 
 // Set up the transport connection and ensure |notifyTransportReady| triggered
 // at both sides.
 function setup() {
-  clientTransport = Cc["@mozilla.org/presentation/presentationsessiontransport;1"]
-                      .createInstance(Ci.nsIPresentationSessionTransport);
-  clientTransport.initWithChannelDescription(serverChannelDescription, clientCallback);
+  clientBuilder = Cc["@mozilla.org/presentation/presentationtcpsessiontransport;1"]
+                    .createInstance(Ci.nsIPresentationTCPSessionTransportBuilder);
+  clientBuilder.buildTCPReceiverTransport(serverChannelDescription, clientListener);
 }
 
 // Test |selfAddress| attribute of |nsIPresentationSessionTransport|.
 function selfAddress() {
   var serverSelfAddress = serverTransport.selfAddress;
   Assert.equal(serverSelfAddress.address, address.data, "The self address of server transport should be set.");
   Assert.equal(serverSelfAddress.port, testServer.serverSocket.port, "The port of server transport should be set.");
 
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -258,17 +258,17 @@ static void Shutdown();
 #ifdef MOZ_WIDGET_GONK
 #include "GonkGPSGeolocationProvider.h"
 #endif
 #include "MediaManager.h"
 
 #include "GMPService.h"
 
 #include "mozilla/dom/PresentationDeviceManager.h"
-#include "mozilla/dom/PresentationSessionTransport.h"
+#include "mozilla/dom/PresentationTCPSessionTransport.h"
 
 #include "mozilla/TextInputProcessor.h"
 
 #ifdef MOZ_B2G
 #include "nsIHardwareKeyHandler.h"
 #include "mozilla/HardwareKeyHandler.h"
 #endif
 
@@ -293,17 +293,17 @@ using mozilla::dom::NotificationTelemetr
 #define TRANSFORMIIX_NODESET_CONTRACTID \
 "@mozilla.org/transformiix-nodeset;1"
 
 // PresentationDeviceManager
 /* e1e79dec-4085-4994-ac5b-744b016697e6 */
 #define PRESENTATION_DEVICE_MANAGER_CID \
 { 0xe1e79dec, 0x4085, 0x4994, { 0xac, 0x5b, 0x74, 0x4b, 0x01, 0x66, 0x97, 0xe6 } }
 
-#define PRESENTATION_SESSION_TRANSPORT_CID \
+#define PRESENTATION_TCP_SESSION_TRANSPORT_CID \
 { 0xc9d023f4, 0x6228, 0x4c07, { 0x8b, 0x1d, 0x9c, 0x19, 0x57, 0x3f, 0xaa, 0x27 } }
 
 already_AddRefed<nsIPresentationService> NS_CreatePresentationService();
 
 // Factory Constructor
 NS_GENERIC_FACTORY_CONSTRUCTOR(txMozillaXSLTProcessor)
 NS_GENERIC_FACTORY_CONSTRUCTOR(XPathEvaluator)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init)
@@ -400,17 +400,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(TVChannel
 NS_GENERIC_FACTORY_CONSTRUCTOR(TVProgramData)
 NS_GENERIC_FACTORY_CONSTRUCTOR(PresentationDeviceManager)
 NS_GENERIC_FACTORY_CONSTRUCTOR(TextInputProcessor)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(FakeInputPortService,
                                          InputPortServiceFactory::CreateFakeInputPortService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(InputPortData)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIPresentationService,
                                          NS_CreatePresentationService)
-NS_GENERIC_FACTORY_CONSTRUCTOR(PresentationSessionTransport)
+NS_GENERIC_FACTORY_CONSTRUCTOR(PresentationTCPSessionTransport)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(NotificationTelemetryService, Init)
 
 #ifndef MOZ_SIMPLEPUSH
 NS_GENERIC_FACTORY_CONSTRUCTOR(PushNotifier)
 #endif
 //-----------------------------------------------------------------------------
 
 static bool gInitialized = false;
@@ -867,17 +867,17 @@ NS_DEFINE_NAMED_CID(TV_PROGRAM_DATA_CID)
 
 NS_DEFINE_NAMED_CID(FAKE_INPUTPORT_SERVICE_CID);
 NS_DEFINE_NAMED_CID(INPUTPORT_DATA_CID);
 
 NS_DEFINE_NAMED_CID(GECKO_MEDIA_PLUGIN_SERVICE_CID);
 
 NS_DEFINE_NAMED_CID(PRESENTATION_SERVICE_CID);
 NS_DEFINE_NAMED_CID(PRESENTATION_DEVICE_MANAGER_CID);
-NS_DEFINE_NAMED_CID(PRESENTATION_SESSION_TRANSPORT_CID);
+NS_DEFINE_NAMED_CID(PRESENTATION_TCP_SESSION_TRANSPORT_CID);
 
 NS_DEFINE_NAMED_CID(TEXT_INPUT_PROCESSOR_CID);
 
 #ifdef MOZ_B2G
 NS_DEFINE_NAMED_CID(NS_HARDWARE_KEY_HANDLER_CID);
 #endif
 
 static nsresult
@@ -1166,17 +1166,17 @@ static const mozilla::Module::CIDEntry k
   { &kTELEPHONY_SERVICE_CID, false, nullptr, nsITelephonyServiceConstructor },
   { &kNS_MOBILE_CONNECTION_SERVICE_CID, false, NULL, nsIMobileConnectionServiceConstructor },
   { &kNS_VOICEMAIL_SERVICE_CID, false, nullptr, nsIVoicemailServiceConstructor },
   { &kTV_TUNER_DATA_CID, false, nullptr, TVTunerDataConstructor },
   { &kTV_CHANNEL_DATA_CID, false, nullptr, TVChannelDataConstructor },
   { &kTV_PROGRAM_DATA_CID, false, nullptr, TVProgramDataConstructor },
   { &kPRESENTATION_SERVICE_CID, false, nullptr, nsIPresentationServiceConstructor },
   { &kPRESENTATION_DEVICE_MANAGER_CID, false, nullptr, PresentationDeviceManagerConstructor },
-  { &kPRESENTATION_SESSION_TRANSPORT_CID, false, nullptr, PresentationSessionTransportConstructor },
+  { &kPRESENTATION_TCP_SESSION_TRANSPORT_CID, false, nullptr, PresentationTCPSessionTransportConstructor },
   { &kTEXT_INPUT_PROCESSOR_CID, false, nullptr, TextInputProcessorConstructor },
   { &kFAKE_INPUTPORT_SERVICE_CID, false, nullptr, FakeInputPortServiceConstructor },
   { &kINPUTPORT_DATA_CID, false, nullptr, InputPortDataConstructor },
 #ifdef MOZ_B2G
   { &kNS_HARDWARE_KEY_HANDLER_CID, false, nullptr, nsIHardwareKeyHandlerConstructor },
 #endif
   { nullptr }
 };
@@ -1335,17 +1335,17 @@ static const mozilla::Module::ContractID
   { TV_TUNER_DATA_CONTRACTID, &kTV_TUNER_DATA_CID },
   { TV_CHANNEL_DATA_CONTRACTID, &kTV_CHANNEL_DATA_CID },
   { TV_PROGRAM_DATA_CONTRACTID, &kTV_PROGRAM_DATA_CID },
   { "@mozilla.org/gecko-media-plugin-service;1",  &kGECKO_MEDIA_PLUGIN_SERVICE_CID },
   { NS_MOBILE_CONNECTION_SERVICE_CONTRACTID, &kNS_MOBILE_CONNECTION_SERVICE_CID },
   { NS_VOICEMAIL_SERVICE_CONTRACTID, &kNS_VOICEMAIL_SERVICE_CID },
   { PRESENTATION_SERVICE_CONTRACTID, &kPRESENTATION_SERVICE_CID },
   { PRESENTATION_DEVICE_MANAGER_CONTRACTID, &kPRESENTATION_DEVICE_MANAGER_CID },
-  { PRESENTATION_SESSION_TRANSPORT_CONTRACTID, &kPRESENTATION_SESSION_TRANSPORT_CID },
+  { PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID, &kPRESENTATION_TCP_SESSION_TRANSPORT_CID },
   { "@mozilla.org/text-input-processor;1", &kTEXT_INPUT_PROCESSOR_CID },
   { FAKE_INPUTPORT_SERVICE_CONTRACTID, &kFAKE_INPUTPORT_SERVICE_CID },
   { INPUTPORT_DATA_CONTRACTID, &kINPUTPORT_DATA_CID },
 #ifdef MOZ_B2G
   { NS_HARDWARE_KEY_HANDLER_CONTRACTID, &kNS_HARDWARE_KEY_HANDLER_CID },
 #endif
   { nullptr }
 };