Bug 1292057 - add NSPR log for Presentation API. r=kershaw draft
authorShih-Chiang Chien <schien@mozilla.com>
Mon, 15 Aug 2016 18:26:13 +0800
changeset 401077 5ce5ddbd12e0b7fc559cb0046b2200ba964fd322
parent 400825 054d4856cea6150a6638e5daf7913713281af97d
child 528388 75a152ffd8e5310fdf43f27a78d58b17a4495d83
push id26354
push userschien@mozilla.com
push dateTue, 16 Aug 2016 06:59:14 +0000
reviewerskershaw
bugs1292057
milestone51.0a1
Bug 1292057 - add NSPR log for Presentation API. r=kershaw MozReview-Commit-ID: Ko1BrG99Uqj
dom/presentation/PresentationConnection.cpp
dom/presentation/PresentationReceiver.cpp
dom/presentation/PresentationService.cpp
dom/presentation/PresentationSessionInfo.cpp
dom/presentation/ipc/PresentationIPCService.cpp
testing/profiles/prefs_general.js
--- a/dom/presentation/PresentationConnection.cpp
+++ b/dom/presentation/PresentationConnection.cpp
@@ -14,16 +14,17 @@
 #include "mozilla/dom/PresentationConnectionClosedEvent.h"
 #include "mozilla/ErrorNames.h"
 #include "nsContentUtils.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIPresentationService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStringStream.h"
 #include "PresentationConnectionList.h"
+#include "PresentationLog.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(PresentationConnection)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PresentationConnection, DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningConnectionList)
@@ -109,16 +110,19 @@ PresentationConnection::Init()
   }
 
   return true;
 }
 
 void
 PresentationConnection::Shutdown()
 {
+  PRES_DEBUG("connection shutdown:id[%s], role[%d]\n",
+             NS_ConvertUTF16toUTF8(mId).get(), mRole);
+
   nsCOMPtr<nsIPresentationService> service =
     do_GetService(PRESENTATION_SERVICE_CONTRACTID);
   if (NS_WARN_IF(!service)) {
     return;
   }
 
   nsresult rv = service->UnregisterSessionListener(mId, mRole);
   NS_WARN_IF(NS_FAILED(rv));
@@ -236,16 +240,20 @@ PresentationConnection::Equals(uint64_t 
          mId.Equals(aId);
 }
 
 NS_IMETHODIMP
 PresentationConnection::NotifyStateChange(const nsAString& aSessionId,
                                           uint16_t aState,
                                           nsresult aReason)
 {
+  PRES_DEBUG("connection state change:id[%s], state[%x], reason[%x], role[%d]\n",
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aState,
+             aReason, mRole);
+
   if (!aSessionId.Equals(mId)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   PresentationConnectionState state;
   switch (aState) {
     case nsIPresentationSessionListener::STATE_CONNECTING:
       state = PresentationConnectionState::Connecting;
@@ -339,16 +347,20 @@ PresentationConnection::ProcessStateChan
       return NS_ERROR_INVALID_ARG;
   }
 }
 
 NS_IMETHODIMP
 PresentationConnection::NotifyMessage(const nsAString& aSessionId,
                                       const nsACString& aData)
 {
+  PRES_DEBUG("connection %s:id[%s], data[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(),
+             nsPromiseFlatCString(aData).get(), mRole);
+
   if (!aSessionId.Equals(mId)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   // No message should be expected when the session is not connected.
   if (NS_WARN_IF(mState != PresentationConnectionState::Connected)) {
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
@@ -366,16 +378,19 @@ PresentationConnection::NotifyMessage(co
   }
 
   return DispatchMessageEvent(jsData);
 }
 
 NS_IMETHODIMP
 PresentationConnection::NotifyReplaced()
 {
+  PRES_DEBUG("connection %s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mId).get(), mRole);
+
   return NotifyStateChange(mId,
                            nsIPresentationSessionListener::STATE_CLOSED,
                            NS_OK);
 }
 
 nsresult
 PresentationConnection::DispatchConnectionClosedEvent(
   PresentationConnectionClosedReason aReason,
--- a/dom/presentation/PresentationReceiver.cpp
+++ b/dom/presentation/PresentationReceiver.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/dom/PresentationReceiverBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "nsContentUtils.h"
 #include "nsIPresentationService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "PresentationConnection.h"
 #include "PresentationConnectionList.h"
+#include "PresentationLog.h"
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PresentationReceiver,
                                       mOwner,
                                       mGetConnectionListPromise,
                                       mConnectionList)
@@ -61,16 +62,18 @@ PresentationReceiver::Init()
   MOZ_ASSERT(docShell);
 
   nsContentUtils::GetPresentationURL(docShell, mUrl);
   return !mUrl.IsEmpty();
 }
 
 void PresentationReceiver::Shutdown()
 {
+  PRES_DEBUG("receiver shutdown:windowId[%d]\n", mWindowId);
+
   // Unregister listener for incoming sessions.
   nsCOMPtr<nsIPresentationService> service =
     do_GetService(PRESENTATION_SERVICE_CONTRACTID);
   if (NS_WARN_IF(!service)) {
     return;
   }
 
   nsresult rv = service->UnregisterRespondingListener(mWindowId);
@@ -83,16 +86,19 @@ PresentationReceiver::WrapObject(JSConte
 {
   return PresentationReceiverBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 PresentationReceiver::NotifySessionConnect(uint64_t aWindowId,
                                            const nsAString& aSessionId)
 {
+  PRES_DEBUG("receiver session connect:id[%s], windowId[%x]\n",
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aWindowId);
+
   if (NS_WARN_IF(!mOwner)) {
     return NS_ERROR_FAILURE;
   }
 
   if (NS_WARN_IF(aWindowId != mWindowId)) {
     return NS_ERROR_INVALID_ARG;
   }
 
--- a/dom/presentation/PresentationService.cpp
+++ b/dom/presentation/PresentationService.cpp
@@ -298,16 +298,18 @@ PresentationService::HandleShutdown()
     obs->RemoveObserver(this, PRESENTATION_TERMINATE_REQUEST_TOPIC);
     obs->RemoveObserver(this, PRESENTATION_RECONNECT_REQUEST_TOPIC);
   }
 }
 
 nsresult
 PresentationService::HandleDeviceChange()
 {
+  PRES_DEBUG("%s\n", __func__);
+
   nsCOMPtr<nsIPresentationDeviceManager> deviceManager =
     do_GetService(PRESENTATION_DEVICE_MANAGER_CONTRACTID);
   if (NS_WARN_IF(!deviceManager)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   bool isAvailable;
   nsresult rv = deviceManager->GetDeviceAvailable(&isAvailable);
@@ -378,23 +380,30 @@ PresentationService::HandleSessionReques
   // Create or reuse session info.
   RefPtr<PresentationSessionInfo> info =
     GetSessionInfo(sessionId, nsIPresentationService::ROLE_RECEIVER);
 
   // This is the case for reconnecting a session.
   // Update the control channel and device of the session info.
   // Call |NotifyResponderReady| to indicate the receiver page is already there.
   if (info) {
+    PRES_DEBUG("handle reconnection:id[%s]\n",
+               NS_ConvertUTF16toUTF8(sessionId).get());
+
     info->SetControlChannel(ctrlChannel);
     info->SetDevice(device);
     return static_cast<PresentationPresentingInfo*>(
       info.get())->NotifyResponderReady();
   }
 
   // This is the case for a new session.
+  PRES_DEBUG("handle new session:url[%d], id[%s]\n",
+             NS_ConvertUTF16toUTF8(url).get(),
+             NS_ConvertUTF16toUTF8(sessionId).get());
+
   info = new PresentationPresentingInfo(url, sessionId, device);
   rv = info->Init(ctrlChannel);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     ctrlChannel->Disconnect(rv);
     return rv;
   }
 
   mSessionInfoAtReceiver.Put(sessionId, info);
@@ -462,16 +471,19 @@ PresentationService::HandleTerminateRequ
 
   // Check if terminate request comes from known device.
   RefPtr<nsIPresentationDevice> knownDevice = info->GetDevice();
   if (NS_WARN_IF(!IsSameDevice(device, knownDevice))) {
     ctrlChannel->Disconnect(NS_ERROR_DOM_OPERATION_ERR);
     return NS_ERROR_DOM_ABORT_ERR;
   }
 
+  PRES_DEBUG("handle termination:id[%s], receiver[%d]\n", __func__,
+             sessionId.get(), isFromReceiver);
+
   return info->OnTerminate(ctrlChannel);
 }
 
 nsresult
 PresentationService::HandleReconnectRequest(nsIPresentationSessionRequest* aRequest)
 {
   nsCOMPtr<nsIPresentationControlChannel> ctrlChannel;
   nsresult rv = aRequest->GetControlChannel(getter_AddRefs(ctrlChannel));
@@ -557,16 +569,20 @@ PresentationService::IsAppInstalled(nsIU
 NS_IMETHODIMP
 PresentationService::StartSession(const nsAString& aUrl,
                                   const nsAString& aSessionId,
                                   const nsAString& aOrigin,
                                   const nsAString& aDeviceId,
                                   uint64_t aWindowId,
                                   nsIPresentationServiceCallback* aCallback)
 {
+  PRES_DEBUG("%s:url[%s], id[%s]\n", __func__,
+             NS_ConvertUTF16toUTF8(aUrl).get(),
+             NS_ConvertUTF16toUTF8(aSessionId).get());
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aCallback);
   MOZ_ASSERT(!aSessionId.IsEmpty());
 
   nsCOMPtr<nsIPresentationDeviceRequest> request =
     new PresentationDeviceRequest(aUrl,
                                   aSessionId,
                                   aOrigin,
@@ -666,16 +682,19 @@ PresentationService::SendSessionMessage(
   return info->Send(aData);
 }
 
 NS_IMETHODIMP
 PresentationService::CloseSession(const nsAString& aSessionId,
                                   uint8_t aRole,
                                   uint8_t aClosedReason)
 {
+  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aClosedReason, aRole);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
 
   RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
   if (NS_WARN_IF(!info)) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -689,16 +708,19 @@ PresentationService::CloseSession(const 
 
   return info->Close(NS_OK, nsIPresentationSessionListener::STATE_CLOSED);
 }
 
 NS_IMETHODIMP
 PresentationService::TerminateSession(const nsAString& aSessionId,
                                       uint8_t aRole)
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
 
   RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
   if (NS_WARN_IF(!info)) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -708,16 +730,20 @@ PresentationService::TerminateSession(co
 }
 
 NS_IMETHODIMP
 PresentationService::ReconnectSession(const nsAString& aUrl,
                                       const nsAString& aSessionId,
                                       uint8_t aRole,
                                       nsIPresentationServiceCallback* aCallback)
 {
+  PRES_DEBUG("%s:url[%s], id[%s]\n", __func__,
+             NS_ConvertUTF16toUTF8(aUrl).get(),
+             NS_ConvertUTF16toUTF8(aSessionId).get());
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(aCallback);
 
   if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
     MOZ_ASSERT(false, "Only controller can call ReconnectSession.");
     return NS_ERROR_INVALID_ARG;
   }
@@ -780,16 +806,19 @@ PresentationService::UnregisterAvailabil
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationService::RegisterSessionListener(const nsAString& aSessionId,
                                              uint8_t aRole,
                                              nsIPresentationSessionListener* aListener)
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aListener);
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
 
   RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
   if (NS_WARN_IF(!info)) {
     // Notify the listener of TERMINATED since no correspondent session info is
@@ -807,16 +836,19 @@ PresentationService::RegisterSessionList
 
   return info->SetListener(aListener);
 }
 
 NS_IMETHODIMP
 PresentationService::UnregisterSessionListener(const nsAString& aSessionId,
                                                uint8_t aRole)
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
 
   RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
   if (info) {
     // When content side decide not handling this session anymore, simply
     // close the connection. Session info is kept for reconnection.
@@ -826,16 +858,19 @@ PresentationService::UnregisterSessionLi
   return NS_OK;
 }
 
 nsresult
 PresentationService::RegisterTransportBuilder(const nsAString& aSessionId,
                                               uint8_t aRole,
                                               nsIPresentationSessionTransportBuilder* aBuilder)
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aBuilder);
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
 
   RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
   if (NS_WARN_IF(!info)) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -845,16 +880,18 @@ PresentationService::RegisterTransportBu
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationService::RegisterRespondingListener(
   uint64_t aWindowId,
   nsIPresentationRespondingListener* aListener)
 {
+  PRES_DEBUG("%s:windowId[%lld]\n", __func__, aWindowId);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aListener);
 
   nsCOMPtr<nsIPresentationRespondingListener> listener;
   if (mRespondingListeners.Get(aWindowId, getter_AddRefs(listener))) {
     return (listener == aListener) ? NS_OK : NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
@@ -869,16 +906,18 @@ PresentationService::RegisterRespondingL
 
   mRespondingListeners.Put(aWindowId, aListener);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationService::UnregisterRespondingListener(uint64_t aWindowId)
 {
+  PRES_DEBUG("%s:windowId[%lld]\n", __func__, aWindowId);
+
   MOZ_ASSERT(NS_IsMainThread());
 
   mRespondingListeners.Remove(aWindowId);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationService::GetExistentSessionIdAtLaunch(uint64_t aWindowId,
@@ -887,16 +926,19 @@ PresentationService::GetExistentSessionI
   return GetExistentSessionIdAtLaunchInternal(aWindowId, aSessionId);
 }
 
 NS_IMETHODIMP
 PresentationService::NotifyReceiverReady(const nsAString& aSessionId,
                                          uint64_t aWindowId,
                                          bool aIsLoading)
 {
+  PRES_DEBUG("%s:id[%s], windowId[%lld], loading[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aWindowId, aIsLoading);
+
   RefPtr<PresentationSessionInfo> info =
     GetSessionInfo(aSessionId, nsIPresentationService::ROLE_RECEIVER);
   if (NS_WARN_IF(!info)) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   AddRespondingSessionId(aWindowId, aSessionId);
 
@@ -913,17 +955,21 @@ PresentationService::NotifyReceiverReady
   }
 
   return static_cast<PresentationPresentingInfo*>(info.get())->NotifyResponderReady();
 }
 
 nsresult
 PresentationService::NotifyTransportClosed(const nsAString& aSessionId,
                                            uint8_t aRole,
-                                           nsresult aReason) {
+                                           nsresult aReason)
+{
+  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aReason, aRole);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!aSessionId.IsEmpty());
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
 
   RefPtr<PresentationSessionInfo> info = GetSessionInfo(aSessionId, aRole);
   if (NS_WARN_IF(!info)) {
     return NS_ERROR_NOT_AVAILABLE;
@@ -931,27 +977,32 @@ PresentationService::NotifyTransportClos
 
   return info->NotifyTransportClosed(aReason);
 }
 
 NS_IMETHODIMP
 PresentationService::UntrackSessionInfo(const nsAString& aSessionId,
                                         uint8_t aRole)
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);
+
   MOZ_ASSERT(aRole == nsIPresentationService::ROLE_CONTROLLER ||
              aRole == nsIPresentationService::ROLE_RECEIVER);
   // Remove the session info.
   if (nsIPresentationService::ROLE_CONTROLLER == aRole) {
     mSessionInfoAtController.Remove(aSessionId);
   } else {
     // Terminate receiver page.
     uint64_t windowId;
     nsresult rv = GetWindowIdBySessionIdInternal(aSessionId, &windowId);
     if (NS_SUCCEEDED(rv)) {
       NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void {
+        PRES_DEBUG("Attempt to close window[%d]\n", windowId);
+
         if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) {
           window->Close();
         }
       }));
     }
 
     mSessionInfoAtReceiver.Remove(aSessionId);
   }
--- a/dom/presentation/PresentationSessionInfo.cpp
+++ b/dom/presentation/PresentationSessionInfo.cpp
@@ -217,16 +217,19 @@ PresentationSessionInfo::Init(nsIPresent
 {
   SetControlChannel(aControlChannel);
   return NS_OK;
 }
 
 /* virtual */ void
 PresentationSessionInfo::Shutdown(nsresult aReason)
 {
+  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole);
+
   NS_WARN_IF(NS_FAILED(aReason));
 
   // Close the control channel if any.
   if (mControlChannel) {
     NS_WARN_IF(NS_FAILED(mControlChannel->Disconnect(aReason)));
   }
 
   // Close the data transport channel if any.
@@ -395,16 +398,19 @@ PresentationSessionInfo::ContinueTermina
     Shutdown(NS_OK);
   }
 }
 
 // nsIPresentationSessionTransportCallback
 NS_IMETHODIMP
 PresentationSessionInfo::NotifyTransportReady()
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), mRole);
+
   MOZ_ASSERT(NS_IsMainThread());
 
   mIsTransportReady = true;
 
   // Established RTCDataChannel implies responder is ready.
   if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) {
     mIsResponderReady = true;
   }
@@ -418,16 +424,19 @@ PresentationSessionInfo::NotifyTransport
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationSessionInfo::NotifyTransportClosed(nsresult aReason)
 {
+  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole);
+
   MOZ_ASSERT(NS_IsMainThread());
 
   // Nullify |mTransport| here so it won't try to re-close |mTransport| in
   // potential subsequent |Shutdown| calls.
   mTransport = nullptr;
 
   if (NS_WARN_IF(!IsSessionReady() &&
                  mState == nsIPresentationSessionListener::STATE_CONNECTING)) {
@@ -468,16 +477,19 @@ PresentationSessionInfo::NotifyData(cons
 
   return mListener->NotifyMessage(mSessionId, aData);
 }
 
 // nsIPresentationSessionTransportBuilderListener
 NS_IMETHODIMP
 PresentationSessionInfo::OnSessionTransport(nsIPresentationSessionTransport* transport)
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), mRole);
+
   SetBuilder(nullptr);
 
   // The session transport is managed by content process
   if (!transport) {
     return NS_OK;
   }
 
   mTransport = transport;
@@ -490,20 +502,23 @@ PresentationSessionInfo::OnSessionTransp
   if (mListener) {
     mTransport->EnableDataNotification();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-PresentationSessionInfo::OnError(nsresult reason)
+PresentationSessionInfo::OnError(nsresult aReason)
 {
+  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole);
+
   SetBuilder(nullptr);
-  return ReplyError(reason);
+  return ReplyError(aReason);
 }
 
 NS_IMETHODIMP
 PresentationSessionInfo::SendOffer(nsIPresentationChannelDescription* aOffer)
 {
   return mControlChannel->SendOffer(aOffer);
 }
 
@@ -733,16 +748,19 @@ PresentationControllingInfo::OnAnswer(ns
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationControllingInfo::NotifyConnected()
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), mRole);
+
   MOZ_ASSERT(NS_IsMainThread());
 
   switch (mState) {
     case nsIPresentationSessionListener::STATE_CONNECTING: {
       nsresult rv = mControlChannel->Launch(GetSessionId(), GetUrl());
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
@@ -758,16 +776,19 @@ PresentationControllingInfo::NotifyConne
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationControllingInfo::NotifyReconnected()
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), mRole);
+
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mReconnectCallback);
 
   if (NS_WARN_IF(mState == nsIPresentationSessionListener::STATE_TERMINATED)) {
     return NS_ERROR_FAILURE;
   }
 
   SetStateWithReason(nsIPresentationSessionListener::STATE_CONNECTING, NS_OK);
@@ -830,16 +851,19 @@ PresentationControllingInfo::BuildTransp
     return rv;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationControllingInfo::NotifyDisconnected(nsresult aReason)
 {
+  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole);
+
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) {
     nsCOMPtr<nsIPresentationDataChannelSessionTransportBuilder>
       builder = do_QueryInterface(mBuilder);
     if (builder) {
       NS_WARN_IF(NS_FAILED(builder->NotifyDisconnected(aReason)));
     }
@@ -886,16 +910,18 @@ PresentationControllingInfo::OnSocketAcc
   mTransportType = nsIPresentationChannelDescription::TYPE_TCP;
   return builder->BuildTCPSenderTransport(aTransport, this);
 }
 
 NS_IMETHODIMP
 PresentationControllingInfo::OnStopListening(nsIServerSocket* aServerSocket,
                                            nsresult aStatus)
 {
+  PRES_DEBUG("controller %s:status[%x]\n",__func__, aStatus);
+
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aStatus == NS_BINDING_ABORTED) { // The server socket was manually closed.
     return NS_OK;
   }
 
   Shutdown(aStatus);
 
@@ -1228,16 +1254,19 @@ PresentationPresentingInfo::IsAccessible
   return (mContentParent) ?
           aProcessId == static_cast<ContentParent*>(mContentParent.get())->OtherPid() :
           false;
 }
 
 nsresult
 PresentationPresentingInfo::NotifyResponderReady()
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), mRole);
+
   if (mTimer) {
     mTimer->Cancel();
     mTimer = nullptr;
   }
 
   mIsResponderReady = true;
 
   // Initialize |mTransport| and send the answer to the sender if sender's
@@ -1250,16 +1279,19 @@ PresentationPresentingInfo::NotifyRespon
   }
 
   return NS_OK;
 }
 
 nsresult
 PresentationPresentingInfo::NotifyResponderFailure()
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), mRole);
+
   if (mTimer) {
     mTimer->Cancel();
     mTimer = nullptr;
   }
 
   return ReplyError(NS_ERROR_DOM_OPERATION_ERR);
 }
 
@@ -1312,16 +1344,19 @@ PresentationPresentingInfo::OnIceCandida
     builder = do_QueryInterface(mBuilder);
 
   return builder->OnIceCandidate(aCandidate);
 }
 
 NS_IMETHODIMP
 PresentationPresentingInfo::NotifyConnected()
 {
+  PRES_DEBUG("%s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), mRole);
+
   if (nsIPresentationSessionListener::STATE_TERMINATED == mState) {
     ContinueTermination();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -1329,16 +1364,19 @@ PresentationPresentingInfo::NotifyReconn
 {
   MOZ_ASSERT(false, "NotifyReconnected should not be called at receiver side.");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationPresentingInfo::NotifyDisconnected(nsresult aReason)
 {
+  PRES_DEBUG("%s:id[%s], reason[%x], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(mSessionId).get(), aReason, mRole);
+
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) {
     nsCOMPtr<nsIPresentationDataChannelSessionTransportBuilder>
       builder = do_QueryInterface(mBuilder);
     if (builder) {
       NS_WARN_IF(NS_FAILED(builder->NotifyDisconnected(aReason)));
     }
--- a/dom/presentation/ipc/PresentationIPCService.cpp
+++ b/dom/presentation/ipc/PresentationIPCService.cpp
@@ -9,16 +9,17 @@
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "nsGlobalWindow.h"
 #include "nsIPresentationListener.h"
 #include "PresentationCallbacks.h"
 #include "PresentationChild.h"
 #include "PresentationContentSessionInfo.h"
 #include "PresentationIPCService.h"
+#include "PresentationLog.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace {
 
 PresentationChild* sPresentationChild;
@@ -386,21 +387,26 @@ PresentationIPCService::NotifyReceiverRe
   mCallback = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PresentationIPCService::UntrackSessionInfo(const nsAString& aSessionId,
                                            uint8_t aRole)
 {
+  PRES_DEBUG("content %s:id[%s], role[%d]\n", __func__,
+             NS_ConvertUTF16toUTF8(aSessionId).get(), aRole);
+
   if (nsIPresentationService::ROLE_RECEIVER == aRole) {
     // Terminate receiver page.
     uint64_t windowId;
     if (NS_SUCCEEDED(GetWindowIdBySessionIdInternal(aSessionId, &windowId))) {
       NS_DispatchToMainThread(NS_NewRunnableFunction([windowId]() -> void {
+        PRES_DEBUG("Attempt to close window[%d]\n", windowId);
+
         if (auto* window = nsGlobalWindow::GetInnerWindowWithId(windowId)) {
           window->Close();
         }
       }));
     }
   }
 
   // Remove the OOP responding info (if it has never been used).
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -226,16 +226,18 @@ user_pref("browser.snippets.firstrunHome
 // Disable useragent updates.
 user_pref("general.useragent.updates.enabled", false);
 
 // Disable webapp updates.  Yes, it is supposed to be an integer.
 user_pref("browser.webapps.checkForUpdates", 0);
 
 // Enable debug logging in the tcp presentation server.
 user_pref("dom.presentation.tcp_server.debug", true);
+// Enable debug logging in the presentation core service.
+pref("logging.Presentation", "debug");
 
 // Don't connect to Yahoo! for RSS feed tests.
 // en-US only uses .types.0.uri, but set all of them just to be sure.
 user_pref('browser.contentHandlers.types.0.uri', 'http://test1.example.org/rss?url=%%s')
 user_pref('browser.contentHandlers.types.1.uri', 'http://test1.example.org/rss?url=%%s')
 user_pref('browser.contentHandlers.types.2.uri', 'http://test1.example.org/rss?url=%%s')
 user_pref('browser.contentHandlers.types.3.uri', 'http://test1.example.org/rss?url=%%s')
 user_pref('browser.contentHandlers.types.4.uri', 'http://test1.example.org/rss?url=%%s')