--- a/dom/presentation/PresentationCallbacks.cpp
+++ b/dom/presentation/PresentationCallbacks.cpp
@@ -105,16 +105,20 @@ PresentationReconnectCallback::NotifySuc
return NS_ERROR_NOT_AVAILABLE;
}
nsresult rv = NS_OK;
// We found a matched connection with the same window ID, URL, and
// the session ID. Resolve the promise with this connection and dispatch
// the event.
if (mConnection) {
+ mConnection->NotifyStateChange(
+ mSessionId,
+ nsIPresentationSessionListener::STATE_CONNECTING,
+ NS_OK);
mPromise->MaybeResolve(mConnection);
rv = mRequest->DispatchConnectionAvailableEvent(mConnection);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
// Use |PresentationRequesterCallback::NotifySuccess| to create a new
// connection since we don't find one that can be reused.
@@ -137,16 +141,22 @@ PresentationReconnectCallback::NotifySuc
service->BuildTransport(sessionId,
nsIPresentationService::ROLE_CONTROLLER);
}));
}
NS_IMETHODIMP
PresentationReconnectCallback::NotifyError(nsresult aError)
{
+ if (mConnection) {
+ mConnection->NotifyStateChange(
+ mSessionId,
+ nsIPresentationSessionListener::STATE_CLOSED,
+ aError);
+ }
return PresentationRequesterCallback::NotifyError(aError);
}
NS_IMPL_ISUPPORTS(PresentationResponderLoadingCallback,
nsIWebProgressListener,
nsISupportsWeakReference)
PresentationResponderLoadingCallback::PresentationResponderLoadingCallback(const nsAString& aSessionId)
--- a/dom/presentation/PresentationConnection.cpp
+++ b/dom/presentation/PresentationConnection.cpp
@@ -357,16 +357,21 @@ PresentationConnection::NotifyStateChang
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;
}
+ // A terminated connection should always remain in terminated.
+ if (mState == PresentationConnectionState::Terminated) {
+ return NS_OK;
+ }
+
PresentationConnectionState state;
switch (aState) {
case nsIPresentationSessionListener::STATE_CONNECTING:
state = PresentationConnectionState::Connecting;
break;
case nsIPresentationSessionListener::STATE_CONNECTED:
state = PresentationConnectionState::Connected;
break;
@@ -519,27 +524,16 @@ PresentationConnection::DoReceiveMessage
if(NS_WARN_IF(!ToJSValue(cx, utf16Data, &jsData))) {
return NS_ERROR_FAILURE;
}
}
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,
const nsAString& aMessage,
bool aDispatchNow)
{
if (mState != PresentationConnectionState::Closed) {
MOZ_ASSERT(false, "The connection state should be closed.");
--- a/dom/presentation/PresentationSessionInfo.cpp
+++ b/dom/presentation/PresentationSessionInfo.cpp
@@ -242,20 +242,16 @@ PresentationSessionInfo::Shutdown(nsresu
mIsOnTerminating = false;
ResetBuilder();
}
nsresult
PresentationSessionInfo::SetListener(nsIPresentationSessionListener* aListener)
{
- if (mListener && aListener) {
- Unused << NS_WARN_IF(NS_FAILED(mListener->NotifyReplaced()));
- }
-
mListener = aListener;
if (mListener) {
// Enable data notification for the transport channel if it's available.
if (mTransport) {
nsresult rv = mTransport->EnableDataNotification();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@@ -311,20 +307,16 @@ PresentationSessionInfo::SendBlob(nsIDOM
return mTransport->SendBlob(aBlob);
}
nsresult
PresentationSessionInfo::Close(nsresult aReason,
uint32_t aState)
{
- if (NS_WARN_IF(!IsSessionReady())) {
- return NS_ERROR_DOM_INVALID_STATE_ERR;
- }
-
// Do nothing if session is already terminated.
if (nsIPresentationSessionListener::STATE_TERMINATED == mState) {
return NS_OK;
}
SetStateWithReason(aState, aReason);
switch (aState) {
@@ -515,33 +507,32 @@ PresentationSessionInfo::NotifyData(cons
return NS_ERROR_NOT_AVAILABLE;
}
return mListener->NotifyMessage(mSessionId, aData, aIsBinary);
}
// nsIPresentationSessionTransportBuilderListener
NS_IMETHODIMP
-PresentationSessionInfo::OnSessionTransport(nsIPresentationSessionTransport* transport)
+PresentationSessionInfo::OnSessionTransport(nsIPresentationSessionTransport* aTransport)
{
PRES_DEBUG("%s:id[%s], role[%d], state[%d]\n", __func__,
NS_ConvertUTF16toUTF8(mSessionId).get(), mRole, mState);
ResetBuilder();
if (mState != nsIPresentationSessionListener::STATE_CONNECTING) {
return NS_ERROR_FAILURE;
}
- // The session transport is managed by content process
- if (!transport) {
- return NS_OK;
+ if (NS_WARN_IF(!aTransport)) {
+ return NS_ERROR_INVALID_ARG;
}
- mTransport = transport;
+ mTransport = aTransport;
nsresult rv = mTransport->SetCallback(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (mListener) {
mTransport->EnableDataNotification();
@@ -646,18 +637,16 @@ PresentationControllingInfo::Shutdown(ns
{
PresentationSessionInfo::Shutdown(aReason);
// Close the server socket if any.
if (mServerSocket) {
Unused << NS_WARN_IF(NS_FAILED(mServerSocket->Close()));
mServerSocket = nullptr;
}
-
- mIsReconnecting = false;
}
nsresult
PresentationControllingInfo::GetAddress()
{
#if defined(MOZ_WIDGET_GONK)
nsCOMPtr<nsINetworkManager> networkManager =
do_GetService("@mozilla.org/network/manager;1");
@@ -837,23 +826,22 @@ PresentationControllingInfo::NotifyConne
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_CONNECTING)) {
return NS_ERROR_FAILURE;
}
- return mReconnectCallback->NotifySuccess(GetUrl());
+ return NotifyReconnectResult(NS_OK);
}
nsresult
PresentationControllingInfo::BuildTransport()
{
MOZ_ASSERT(NS_IsMainThread());
if (mState != nsIPresentationSessionListener::STATE_CONNECTING) {
@@ -931,18 +919,33 @@ PresentationControllingInfo::NotifyDisco
if (NS_WARN_IF(NS_FAILED(aReason) || !mIsResponderReady)) {
// The presentation session instance may already exist.
// Change the state to CLOSED if it is not terminated.
if (nsIPresentationSessionListener::STATE_TERMINATED != mState) {
SetStateWithReason(nsIPresentationSessionListener::STATE_CLOSED, aReason);
}
- // Reply error for an abnormal close.
- return ReplyError(NS_ERROR_DOM_OPERATION_ERR);
+ // If |aReason| is NS_OK, it implies that the user closes the connection
+ // before becomming connected. No need to call |ReplyError| in this case.
+ if (NS_FAILED(aReason)) {
+ if (mIsReconnecting) {
+ NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR);
+ }
+ // Reply error for an abnormal close.
+ return ReplyError(NS_ERROR_DOM_OPERATION_ERR);
+ }
+ Shutdown(aReason);
+ }
+
+ // This is the case for reconnecting a connection which is in
+ // connecting state and |mTransport| is not ready.
+ if (mDoReconnectAfterClose && !mTransport) {
+ mDoReconnectAfterClose = false;
+ return Reconnect(mReconnectCallback);
}
return NS_OK;
}
// nsIServerSocketListener
NS_IMETHODIMP
PresentationControllingInfo::OnSocketAccepted(nsIServerSocket* aServerSocket,
@@ -1017,60 +1020,72 @@ PresentationControllingInfo::OnStopListe
* 5. Once both step 3 and 4 are done, the rest is to build a new data
* transport channel by following the same steps as starting a
* new session.
*/
nsresult
PresentationControllingInfo::Reconnect(nsIPresentationServiceCallback* aCallback)
{
+ PRES_DEBUG("%s:id[%s], role[%d], state[%d]\n", __func__,
+ NS_ConvertUTF16toUTF8(mSessionId).get(), mRole, mState);
+
if (!aCallback) {
return NS_ERROR_INVALID_ARG;
}
mReconnectCallback = aCallback;
if (NS_WARN_IF(mState == nsIPresentationSessionListener::STATE_TERMINATED)) {
- return mReconnectCallback->NotifyError(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return NotifyReconnectResult(NS_ERROR_DOM_INVALID_STATE_ERR);
}
- SetStateWithReason(nsIPresentationSessionListener::STATE_CONNECTING, NS_OK);
+ // If |mState| is not CLOSED, we have to close the connection before
+ // reconnecting. The process to reconnect will be continued after
+ // |NotifyDisconnected| or |NotifyTransportClosed| is invoked.
+ if (mState == nsIPresentationSessionListener::STATE_CONNECTING ||
+ mState == nsIPresentationSessionListener::STATE_CONNECTED) {
+ mDoReconnectAfterClose = true;
+ return Close(NS_OK, nsIPresentationSessionListener::STATE_CLOSED);
+ }
+
+ // Make sure |mState| is closed at this point.
+ MOZ_ASSERT(mState == nsIPresentationSessionListener::STATE_CLOSED);
+
+ mState = nsIPresentationSessionListener::STATE_CONNECTING;
+ mIsReconnecting = true;
nsresult rv = NS_OK;
if (!mControlChannel) {
nsCOMPtr<nsIPresentationControlChannel> ctrlChannel;
rv = mDevice->EstablishControlChannel(getter_AddRefs(ctrlChannel));
if (NS_WARN_IF(NS_FAILED(rv))) {
- return mReconnectCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
+ return NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR);
}
rv = Init(ctrlChannel);
if (NS_WARN_IF(NS_FAILED(rv))) {
- return mReconnectCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
+ return NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR);
}
-
- mIsReconnecting = true;
} else {
return ContinueReconnect();
}
return NS_OK;
}
nsresult
PresentationControllingInfo::ContinueReconnect()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mControlChannel);
- MOZ_ASSERT(mReconnectCallback);
mIsReconnecting = false;
- if (NS_WARN_IF(NS_FAILED(mControlChannel->Reconnect(mSessionId, GetUrl()))) &&
- mReconnectCallback) {
- return mReconnectCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
+ if (NS_WARN_IF(NS_FAILED(mControlChannel->Reconnect(mSessionId, GetUrl())))) {
+ return NotifyReconnectResult(NS_ERROR_DOM_OPERATION_ERR);
}
return NS_OK;
}
// nsIListNetworkAddressesListener
NS_IMETHODIMP
PresentationControllingInfo::OnListedNetworkAddresses(const char** aAddressArray,
@@ -1110,16 +1125,62 @@ PresentationControllingInfo::OnListNetwo
NewRunnableMethod<nsCString>(
this,
&PresentationControllingInfo::OnGetAddress,
"127.0.0.1"));
return NS_OK;
}
+nsresult
+PresentationControllingInfo::NotifyReconnectResult(nsresult aStatus)
+{
+ if (!mReconnectCallback) {
+ MOZ_ASSERT(false, "mReconnectCallback can not be null here.");
+ return NS_ERROR_FAILURE;
+ }
+
+ mIsReconnecting = false;
+ nsCOMPtr<nsIPresentationServiceCallback> callback =
+ mReconnectCallback.forget();
+ if (NS_FAILED(aStatus)) {
+ return callback->NotifyError(aStatus);
+ }
+
+ return callback->NotifySuccess(GetUrl());
+}
+
+// nsIPresentationSessionTransportCallback
+NS_IMETHODIMP
+PresentationControllingInfo::NotifyTransportReady()
+{
+ return PresentationSessionInfo::NotifyTransportReady();
+}
+
+NS_IMETHODIMP
+PresentationControllingInfo::NotifyTransportClosed(nsresult aReason)
+{
+ if (!mDoReconnectAfterClose) {
+ return PresentationSessionInfo::NotifyTransportClosed(aReason);;
+ }
+
+ MOZ_ASSERT(mState == nsIPresentationSessionListener::STATE_CLOSED);
+
+ mTransport = nullptr;
+ mIsTransportReady = false;
+ mDoReconnectAfterClose = false;
+ return Reconnect(mReconnectCallback);
+}
+
+NS_IMETHODIMP
+PresentationControllingInfo::NotifyData(const nsACString& aData, bool aIsBinary)
+{
+ return PresentationSessionInfo::NotifyData(aData, aIsBinary);
+}
+
/**
* Implementation of PresentationPresentingInfo
*
* During presentation session establishment, the receiver expects the following
* after trying to launch the app by notifying "presentation-launch-receiver":
* (The order between step 2 and 3 is not guaranteed.)
* 1. |Observe| of |nsIObserver| is called with "presentation-receiver-launched".
* Then start listen to document |STATE_TRANSFERRING| event.
@@ -1177,27 +1238,27 @@ PresentationPresentingInfo::Shutdown(nsr
mRequesterDescription = nullptr;
mPendingCandidates.Clear();
mPromise = nullptr;
mHasFlushPendingEvents = false;
}
// nsIPresentationSessionTransportBuilderListener
NS_IMETHODIMP
-PresentationPresentingInfo::OnSessionTransport(nsIPresentationSessionTransport* transport)
+PresentationPresentingInfo::OnSessionTransport(nsIPresentationSessionTransport* aTransport)
{
- nsresult rv = PresentationSessionInfo::OnSessionTransport(transport);
+ nsresult rv = PresentationSessionInfo::OnSessionTransport(aTransport);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// The session transport is managed by content process
- if (!transport) {
- return NS_OK;
+ if (NS_WARN_IF(!aTransport)) {
+ return NS_ERROR_INVALID_ARG;
}
// send answer for TCP session transport
if (mTransportType == nsIPresentationChannelDescription::TYPE_TCP) {
// Prepare and send the answer.
// In the current implementation of |PresentationSessionTransport|,
// |GetSelfAddress| cannot return the real info when it's initialized via
// |buildTCPReceiverTransport|. Yet this deficiency only affects the channel
--- a/dom/presentation/PresentationSessionInfo.h
+++ b/dom/presentation/PresentationSessionInfo.h
@@ -187,16 +187,17 @@ class PresentationControllingInfo final
, public nsIServerSocketListener
, public nsIListNetworkAddressesListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIPRESENTATIONCONTROLCHANNELLISTENER
NS_DECL_NSISERVERSOCKETLISTENER
NS_DECL_NSILISTNETWORKADDRESSESLISTENER
+ NS_DECL_NSIPRESENTATIONSESSIONTRANSPORTCALLBACK
PresentationControllingInfo(const nsAString& aUrl,
const nsAString& aSessionId)
: PresentationSessionInfo(aUrl,
aSessionId,
nsIPresentationService::ROLE_CONTROLLER)
{}
@@ -215,19 +216,22 @@ private:
void Shutdown(nsresult aReason) override;
nsresult GetAddress();
nsresult OnGetAddress(const nsACString& aAddress);
nsresult ContinueReconnect();
+ nsresult NotifyReconnectResult(nsresult aStatus);
+
nsCOMPtr<nsIServerSocket> mServerSocket;
nsCOMPtr<nsIPresentationServiceCallback> mReconnectCallback;
bool mIsReconnecting = false;
+ bool mDoReconnectAfterClose = false;
};
// Session info with presenting browsing context (receiver side) behaviors.
class PresentationPresentingInfo final : public PresentationSessionInfo
, public PromiseNativeHandler
, public nsITimerCallback
{
public:
--- a/dom/presentation/interfaces/nsIPresentationListener.idl
+++ b/dom/presentation/interfaces/nsIPresentationListener.idl
@@ -29,21 +29,16 @@ interface nsIPresentationSessionListener
in nsresult reason);
/*
* Called when receive messages.
*/
void notifyMessage(in DOMString sessionId,
in ACString data,
in boolean isBinary);
-
- /*
- * Called when this listener is replaced by another one.
- */
- void notifyReplaced();
};
[scriptable, uuid(27f101d7-9ed1-429e-b4f8-43b00e8e111c)]
interface nsIPresentationRespondingListener : nsISupports
{
/*
* Called when an incoming session connects.
*/
--- a/dom/presentation/ipc/PPresentation.ipdl
+++ b/dom/presentation/ipc/PPresentation.ipdl
@@ -76,16 +76,19 @@ sync protocol PPresentation
child:
async NotifyAvailableChange(bool aAvailable);
async NotifySessionStateChange(nsString aSessionId,
uint16_t aState,
nsresult aReason);
async NotifyMessage(nsString aSessionId, nsCString aData, bool aIsBinary);
async NotifySessionConnect(uint64_t aWindowId, nsString aSessionId);
+ async NotifyCloseSessionTransport(nsString aSessionId,
+ uint8_t aRole,
+ nsresult aReason);
async PPresentationBuilder(nsString aSessionId, uint8_t aRole);
parent:
async __delete__();
async RegisterAvailabilityHandler();
async UnregisterAvailabilityHandler();
--- a/dom/presentation/ipc/PresentationBuilderParent.cpp
+++ b/dom/presentation/ipc/PresentationBuilderParent.cpp
@@ -6,16 +6,108 @@
#include "DCPresentationChannelDescription.h"
#include "PresentationBuilderParent.h"
#include "PresentationSessionInfo.h"
namespace mozilla {
namespace dom {
+namespace {
+
+class PresentationSessionTransportIPC final :
+ public nsIPresentationSessionTransport
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPRESENTATIONSESSIONTRANSPORT
+
+ PresentationSessionTransportIPC(PresentationParent* aParent,
+ const nsAString& aSessionId,
+ uint8_t aRole)
+ : mParent(aParent)
+ , mSessionId(aSessionId)
+ , mRole(aRole)
+ {
+ MOZ_ASSERT(mParent);
+ }
+
+private:
+ virtual ~PresentationSessionTransportIPC() = default;
+
+ RefPtr<PresentationParent> mParent;
+ nsString mSessionId;
+ uint8_t mRole;
+};
+
+NS_IMPL_ISUPPORTS(PresentationSessionTransportIPC,
+ nsIPresentationSessionTransport)
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::GetCallback(
+ nsIPresentationSessionTransportCallback** aCallback)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::SetCallback(
+ nsIPresentationSessionTransportCallback* aCallback)
+{
+ if (aCallback) {
+ aCallback->NotifyTransportReady();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::GetSelfAddress(nsINetAddr** aSelfAddress)
+{
+ MOZ_ASSERT(false, "Not expected.");
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::EnableDataNotification()
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::Send(const nsAString& aData)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::SendBinaryMsg(const nsACString& aData)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::SendBlob(nsIDOMBlob* aBlob)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationSessionTransportIPC::Close(nsresult aReason)
+{
+ if (NS_WARN_IF(!mParent->SendNotifyCloseSessionTransport(mSessionId,
+ mRole,
+ aReason))) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
+}
+
+} // anonymous namespace
+
NS_IMPL_ISUPPORTS(PresentationBuilderParent,
nsIPresentationSessionTransportBuilder,
nsIPresentationDataChannelSessionTransportBuilder)
PresentationBuilderParent::PresentationBuilderParent(PresentationParent* aParent)
: mParent(aParent)
{
MOZ_COUNT_CTOR(PresentationBuilderParent);
@@ -34,21 +126,25 @@ NS_IMETHODIMP
PresentationBuilderParent::BuildDataChannelTransport(
uint8_t aRole,
mozIDOMWindow* aWindow, /* unused */
nsIPresentationSessionTransportBuilderListener* aListener)
{
mBuilderListener = aListener;
RefPtr<PresentationSessionInfo> info = static_cast<PresentationSessionInfo*>(aListener);
+ nsAutoString sessionId(info->GetSessionId());
if (NS_WARN_IF(!mParent->SendPPresentationBuilderConstructor(this,
- nsString(info->GetSessionId()),
+ sessionId,
aRole))) {
return NS_ERROR_FAILURE;
}
+ mIPCSessionTransport = new PresentationSessionTransportIPC(mParent,
+ sessionId,
+ aRole);
mNeedDestroyActor = true;
mParent = nullptr;
return NS_OK;
}
NS_IMETHODIMP
PresentationBuilderParent::OnIceCandidate(const nsAString& aCandidate)
{
@@ -145,27 +241,20 @@ PresentationBuilderParent::RecvClose(con
}
return true;
}
// Delegate to nsIPresentationSessionTransportBuilderListener
bool
PresentationBuilderParent::RecvOnSessionTransport()
{
- // To avoid releasing |this| in this method
- NS_DispatchToMainThread(NS_NewRunnableFunction([this]() -> void {
- Unused <<
- NS_WARN_IF(!mBuilderListener ||
- NS_FAILED(mBuilderListener->OnSessionTransport(nullptr)));
- }));
-
- nsCOMPtr<nsIPresentationSessionTransportCallback>
- callback(do_QueryInterface(mBuilderListener));
-
- callback->NotifyTransportReady();
+ RefPtr<PresentationBuilderParent> kungFuDeathGrip = this;
+ Unused <<
+ NS_WARN_IF(!mBuilderListener ||
+ NS_FAILED(mBuilderListener->OnSessionTransport(mIPCSessionTransport)));
return true;
}
bool
PresentationBuilderParent::RecvOnSessionTransportError(const nsresult& aReason)
{
if (NS_WARN_IF(!mBuilderListener ||
NS_FAILED(mBuilderListener->OnError(aReason)))) {
--- a/dom/presentation/ipc/PresentationBuilderParent.h
+++ b/dom/presentation/ipc/PresentationBuilderParent.h
@@ -38,14 +38,15 @@ public:
virtual bool RecvOnSessionTransportError(const nsresult& aReason) override;
private:
virtual ~PresentationBuilderParent();
bool mNeedDestroyActor = false;
RefPtr<PresentationParent> mParent;
nsCOMPtr<nsIPresentationSessionTransportBuilderListener> mBuilderListener;
+ nsCOMPtr<nsIPresentationSessionTransport> mIPCSessionTransport;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PresentationBuilderParent_h__
--- a/dom/presentation/ipc/PresentationChild.cpp
+++ b/dom/presentation/ipc/PresentationChild.cpp
@@ -128,16 +128,28 @@ PresentationChild::RecvNotifySessionConn
const nsString& aSessionId)
{
if (mService) {
Unused << NS_WARN_IF(NS_FAILED(mService->NotifySessionConnect(aWindowId, aSessionId)));
}
return true;
}
+bool
+PresentationChild::RecvNotifyCloseSessionTransport(const nsString& aSessionId,
+ const uint8_t& aRole,
+ const nsresult& aReason)
+{
+ if (mService) {
+ Unused << NS_WARN_IF(NS_FAILED(
+ mService->CloseContentSessionTransport(aSessionId, aRole, aReason)));
+ }
+ return true;
+}
+
/*
* Implementation of PresentationRequestChild
*/
PresentationRequestChild::PresentationRequestChild(nsIPresentationServiceCallback* aCallback)
: mActorDestroyed(false)
, mCallback(aCallback)
{
--- a/dom/presentation/ipc/PresentationChild.h
+++ b/dom/presentation/ipc/PresentationChild.h
@@ -54,16 +54,21 @@ public:
RecvNotifyMessage(const nsString& aSessionId,
const nsCString& aData,
const bool& aIsBinary) override;
virtual bool
RecvNotifySessionConnect(const uint64_t& aWindowId,
const nsString& aSessionId) override;
+ virtual bool
+ RecvNotifyCloseSessionTransport(const nsString& aSessionId,
+ const uint8_t& aRole,
+ const nsresult& aReason) override;
+
private:
virtual ~PresentationChild();
bool mActorDestroyed = false;
RefPtr<PresentationIPCService> mService;
};
class PresentationRequestChild final : public PPresentationRequestChild
--- a/dom/presentation/ipc/PresentationIPCService.cpp
+++ b/dom/presentation/ipc/PresentationIPCService.cpp
@@ -263,17 +263,16 @@ PresentationIPCService::RegisterSessionL
uint8_t aRole,
nsIPresentationSessionListener* aListener)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aListener);
nsCOMPtr<nsIPresentationSessionListener> listener;
if (mSessionListeners.Get(aSessionId, getter_AddRefs(listener))) {
- Unused << NS_WARN_IF(NS_FAILED(listener->NotifyReplaced()));
mSessionListeners.Put(aSessionId, aListener);
return NS_OK;
}
mSessionListeners.Put(aSessionId, aListener);
if (sPresentationChild) {
Unused <<
NS_WARN_IF(!sPresentationChild->SendRegisterSessionHandler(
@@ -503,8 +502,22 @@ nsresult
PresentationIPCService::MonitorResponderLoading(const nsAString& aSessionId,
nsIDocShell* aDocShell)
{
MOZ_ASSERT(NS_IsMainThread());
mCallback = new PresentationResponderLoadingCallback(aSessionId);
return mCallback->Init(aDocShell);
}
+
+nsresult
+PresentationIPCService::CloseContentSessionTransport(const nsString& aSessionId,
+ uint8_t aRole,
+ nsresult aReason)
+{
+ RefPtr<PresentationContentSessionInfo> info =
+ GetSessionInfo(aSessionId, aRole);
+ if (NS_WARN_IF(!info)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ return info->Close(aReason);
+}
--- a/dom/presentation/ipc/PresentationIPCService.h
+++ b/dom/presentation/ipc/PresentationIPCService.h
@@ -48,16 +48,20 @@ public:
nsresult MonitorResponderLoading(const nsAString& aSessionId,
nsIDocShell* aDocShell);
nsresult NotifySessionTransport(const nsString& aSessionId,
const uint8_t& aRole,
nsIPresentationSessionTransport* transport);
+ nsresult CloseContentSessionTransport(const nsString& aSessionId,
+ uint8_t aRole,
+ nsresult aReason);
+
private:
virtual ~PresentationIPCService();
nsresult SendRequest(nsIPresentationServiceCallback* aCallback,
const PresentationIPCRequest& aRequest);
nsTObserverArray<nsCOMPtr<nsIPresentationAvailabilityListener> > mAvailabilityListeners;
nsRefPtrHashtable<nsStringHashKey,
nsIPresentationSessionListener> mSessionListeners;
--- a/dom/presentation/ipc/PresentationParent.cpp
+++ b/dom/presentation/ipc/PresentationParent.cpp
@@ -301,24 +301,16 @@ PresentationParent::NotifyStateChange(co
aState,
aReason))) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
-PresentationParent::NotifyReplaced()
-{
- // Do nothing here, since |PresentationIPCService::RegisterSessionListener|
- // already dealt with this in content process.
- return NS_OK;
-}
-
-NS_IMETHODIMP
PresentationParent::NotifyMessage(const nsAString& aSessionId,
const nsACString& aData,
bool aIsBinary)
{
if (NS_WARN_IF(mActorDestroyed ||
!SendNotifyMessage(nsString(aSessionId),
nsCString(aData),
aIsBinary))) {