зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1148307 - Part 4 - use data channel in substitution for TCP session transport (in-process), r=smaug
--HG-- rename : dom/presentation/tests/mochitest/test_presentation_receiver.html => dom/presentation/tests/mochitest/test_presentation_tcp_receiver.html rename : dom/presentation/tests/mochitest/test_presentation_receiver_establish_connection_error.html => dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_error.html rename : dom/presentation/tests/mochitest/test_presentation_receiver_establish_connection_timeout.html => dom/presentation/tests/mochitest/test_presentation_tcp_receiver_establish_connection_timeout.html rename : dom/presentation/tests/mochitest/test_presentation_receiver_oop.html => dom/presentation/tests/mochitest/test_presentation_tcp_receiver_oop.html rename : dom/presentation/tests/mochitest/test_presentation_sender.html => dom/presentation/tests/mochitest/test_presentation_tcp_sender.html rename : dom/presentation/tests/mochitest/test_presentation_sender_default_request.html => dom/presentation/tests/mochitest/test_presentation_tcp_sender_default_request.html rename : dom/presentation/tests/mochitest/test_presentation_sender_disconnect.html => dom/presentation/tests/mochitest/test_presentation_tcp_sender_disconnect.html rename : dom/presentation/tests/mochitest/test_presentation_sender_establish_connection_error.html => dom/presentation/tests/mochitest/test_presentation_tcp_sender_establish_connection_error.html
This commit is contained in:
Родитель
fee05caf8c
Коммит
a8a1aaba30
|
@ -131,7 +131,7 @@ PresentationRequest::StartWithDevice(const nsAString& aDeviceId,
|
||||||
|
|
||||||
nsCOMPtr<nsIPresentationServiceCallback> callback =
|
nsCOMPtr<nsIPresentationServiceCallback> callback =
|
||||||
new PresentationRequesterCallback(this, mUrl, id, promise);
|
new PresentationRequesterCallback(this, mUrl, id, promise);
|
||||||
rv = service->StartSession(mUrl, id, origin, aDeviceId, callback);
|
rv = service->StartSession(mUrl, id, origin, aDeviceId, GetOwner()->WindowID(), callback);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,6 +388,7 @@ PresentationService::StartSession(const nsAString& aUrl,
|
||||||
const nsAString& aSessionId,
|
const nsAString& aSessionId,
|
||||||
const nsAString& aOrigin,
|
const nsAString& aOrigin,
|
||||||
const nsAString& aDeviceId,
|
const nsAString& aDeviceId,
|
||||||
|
uint64_t aWindowId,
|
||||||
nsIPresentationServiceCallback* aCallback)
|
nsIPresentationServiceCallback* aCallback)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
@ -400,6 +401,13 @@ PresentationService::StartSession(const nsAString& aUrl,
|
||||||
new PresentationControllingInfo(aUrl, aSessionId, aCallback);
|
new PresentationControllingInfo(aUrl, aSessionId, aCallback);
|
||||||
mSessionInfo.Put(aSessionId, info);
|
mSessionInfo.Put(aSessionId, info);
|
||||||
|
|
||||||
|
// Only track the info when an actual window ID, which would never be 0, is
|
||||||
|
// provided (for an in-process sender page).
|
||||||
|
if (aWindowId != 0) {
|
||||||
|
mRespondingSessionIds.Put(aWindowId, new nsString(aSessionId));
|
||||||
|
mRespondingWindowIds.Put(aSessionId, aWindowId);
|
||||||
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIPresentationDeviceRequest> request =
|
nsCOMPtr<nsIPresentationDeviceRequest> request =
|
||||||
new PresentationDeviceRequest(aUrl, aSessionId, aOrigin);
|
new PresentationDeviceRequest(aUrl, aSessionId, aOrigin);
|
||||||
|
|
||||||
|
@ -614,7 +622,7 @@ PresentationService::NotifyReceiverReady(const nsAString& aSessionId,
|
||||||
// Only track the responding info when an actual window ID, which would never
|
// Only track the responding info when an actual window ID, which would never
|
||||||
// be 0, is provided (for an in-process receiver page).
|
// be 0, is provided (for an in-process receiver page).
|
||||||
if (aWindowId != 0) {
|
if (aWindowId != 0) {
|
||||||
mRespondingSessionIds.Put(aWindowId, new nsAutoString(aSessionId));
|
mRespondingSessionIds.Put(aWindowId, new nsString(aSessionId));
|
||||||
mRespondingWindowIds.Put(aSessionId, aWindowId);
|
mRespondingWindowIds.Put(aSessionId, aWindowId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,6 +645,16 @@ PresentationService::UntrackSessionInfo(const nsAString& aSessionId)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
PresentationService::GetWindowIdBySessionId(const nsAString& aSessionId,
|
||||||
|
uint64_t* aWindowId)
|
||||||
|
{
|
||||||
|
if (mRespondingWindowIds.Get(aSessionId, aWindowId)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PresentationService::IsSessionAccessible(const nsAString& aSessionId,
|
PresentationService::IsSessionAccessible(const nsAString& aSessionId,
|
||||||
base::ProcessId aProcessId)
|
base::ProcessId aProcessId)
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsIDocShell.h"
|
#include "nsIDocShell.h"
|
||||||
#include "nsIFrameLoader.h"
|
#include "nsIFrameLoader.h"
|
||||||
#include "nsIMutableArray.h"
|
#include "nsIMutableArray.h"
|
||||||
|
@ -153,8 +154,6 @@ TCPPresentationChannelDescription::GetType(uint8_t* aRetVal)
|
||||||
return NS_ERROR_INVALID_POINTER;
|
return NS_ERROR_INVALID_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
|
|
||||||
// Only support TCP socket for now.
|
|
||||||
*aRetVal = nsIPresentationChannelDescription::TYPE_TCP;
|
*aRetVal = nsIPresentationChannelDescription::TYPE_TCP;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -171,11 +170,9 @@ TCPPresentationChannelDescription::GetTcpAddress(nsIArray** aRetVal)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
|
// TODO bug 1228504 Take all IP addresses in PresentationChannelDescription
|
||||||
// Ultimately we may use all the available addresses. DataChannel appears
|
// into account. And at the first stage Presentation API is only exposed on
|
||||||
// more robust upon handling ICE. And at the first stage Presentation API is
|
// Firefox OS where the first IP appears enough for most scenarios.
|
||||||
// only exposed on Firefox OS where the first IP appears enough for most
|
|
||||||
// scenarios.
|
|
||||||
nsCOMPtr<nsISupportsCString> address = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
nsCOMPtr<nsISupportsCString> address = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID);
|
||||||
if (NS_WARN_IF(!address)) {
|
if (NS_WARN_IF(!address)) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
@ -202,8 +199,6 @@ TCPPresentationChannelDescription::GetTcpPort(uint16_t* aRetVal)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
TCPPresentationChannelDescription::GetDataChannelSDP(nsAString& aDataChannelSDP)
|
TCPPresentationChannelDescription::GetDataChannelSDP(nsAString& aDataChannelSDP)
|
||||||
{
|
{
|
||||||
// TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
|
|
||||||
// Only support TCP socket for now.
|
|
||||||
aDataChannelSDP.Truncate();
|
aDataChannelSDP.Truncate();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -241,6 +236,8 @@ PresentationSessionInfo::Shutdown(nsresult aReason)
|
||||||
}
|
}
|
||||||
|
|
||||||
mIsResponderReady = false;
|
mIsResponderReady = false;
|
||||||
|
|
||||||
|
mBuilder = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -333,6 +330,22 @@ PresentationSessionInfo::UntrackFromService()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsPIDOMWindowInner*
|
||||||
|
PresentationSessionInfo::GetWindow()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIPresentationService> service =
|
||||||
|
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
||||||
|
if (NS_WARN_IF(!service)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
uint64_t windowId = 0;
|
||||||
|
if (NS_WARN_IF(NS_FAILED(service->GetWindowIdBySessionId(mSessionId, &windowId)))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nsGlobalWindow::GetInnerWindowWithId(windowId)->AsInner();
|
||||||
|
}
|
||||||
|
|
||||||
/* virtual */ bool
|
/* virtual */ bool
|
||||||
PresentationSessionInfo::IsAccessible(base::ProcessId aProcessId)
|
PresentationSessionInfo::IsAccessible(base::ProcessId aProcessId)
|
||||||
{
|
{
|
||||||
|
@ -428,11 +441,10 @@ PresentationSessionInfo::OnSessionTransport(nsIPresentationSessionTransport* tra
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PresentationSessionInfo::OnError(nsresult reason)
|
PresentationSessionInfo::OnError(nsresult reason)
|
||||||
{
|
{
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return ReplyError(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
|
||||||
* Implementation of PresentationControllingInfo
|
* Implementation of PresentationControllingInfo
|
||||||
*
|
*
|
||||||
* During presentation session establishment, the sender expects the following
|
* During presentation session establishment, the sender expects the following
|
||||||
|
@ -527,11 +539,10 @@ PresentationControllingInfo::GetAddress()
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
|
// TODO bug 1228504 Take all IP addresses in PresentationChannelDescription
|
||||||
// Ultimately we may use all the available addresses. DataChannel appears
|
// into account. And at the first stage Presentation API is only exposed on
|
||||||
// more robust upon handling ICE. And at the first stage Presentation API is
|
// Firefox OS where the first IP appears enough for most scenarios.
|
||||||
// only exposed on Firefox OS where the first IP appears enough for most
|
|
||||||
// scenarios.
|
|
||||||
nsAutoString ip;
|
nsAutoString ip;
|
||||||
ip.Assign(ips[0]);
|
ip.Assign(ips[0]);
|
||||||
|
|
||||||
|
@ -633,9 +644,29 @@ NS_IMETHODIMP
|
||||||
PresentationControllingInfo::NotifyOpened()
|
PresentationControllingInfo::NotifyOpened()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
|
if (!Preferences::GetBool("dom.presentation.session_transport.data_channel.enable")) {
|
||||||
|
// Build TCP session transport
|
||||||
return GetAddress();
|
return GetAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPresentationDataChannelSessionTransportBuilder> builder =
|
||||||
|
do_CreateInstance("@mozilla.org/presentation/datachanneltransportbuilder;1");
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!builder)) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBuilder = builder;
|
||||||
|
mTransportType = nsIPresentationChannelDescription::TYPE_DATACHANNEL;
|
||||||
|
|
||||||
|
return builder->BuildDataChannelTransport(nsIPresentationSessionTransportBuilder::TYPE_SENDER,
|
||||||
|
GetWindow(),
|
||||||
|
mControlChannel,
|
||||||
|
this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PresentationControllingInfo::NotifyClosed(nsresult aReason)
|
PresentationControllingInfo::NotifyClosed(nsresult aReason)
|
||||||
{
|
{
|
||||||
|
@ -677,6 +708,7 @@ PresentationControllingInfo::OnSocketAccepted(nsIServerSocket* aServerSocket,
|
||||||
return ReplyError(NS_ERROR_DOM_OPERATION_ERR);
|
return ReplyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTransportType = nsIPresentationChannelDescription::TYPE_TCP;
|
||||||
return builder->BuildTCPSenderTransport(aTransport, this);
|
return builder->BuildTCPSenderTransport(aTransport, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +735,7 @@ PresentationControllingInfo::OnStopListening(nsIServerSocket* aServerSocket,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Implementation of PresentationPresentingInfo
|
* Implementation of PresentationPresentingInfo
|
||||||
*
|
*
|
||||||
* During presentation session establishment, the receiver expects the following
|
* During presentation session establishment, the receiver expects the following
|
||||||
|
@ -766,16 +798,21 @@ PresentationPresentingInfo::Shutdown(nsresult aReason)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PresentationPresentingInfo::OnSessionTransport(nsIPresentationSessionTransport* transport)
|
PresentationPresentingInfo::OnSessionTransport(nsIPresentationSessionTransport* transport)
|
||||||
{
|
{
|
||||||
PresentationSessionInfo::OnSessionTransport(transport);
|
nsresult rv = PresentationSessionInfo::OnSessionTransport(transport);
|
||||||
|
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send answer for TCP session transport
|
||||||
|
if (mTransportType == nsIPresentationChannelDescription::TYPE_TCP) {
|
||||||
// Prepare and send the answer.
|
// Prepare and send the answer.
|
||||||
// TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
|
|
||||||
// In the current implementation of |PresentationSessionTransport|,
|
// In the current implementation of |PresentationSessionTransport|,
|
||||||
// |GetSelfAddress| cannot return the real info when it's initialized via
|
// |GetSelfAddress| cannot return the real info when it's initialized via
|
||||||
// |InitWithChannelDescription|. Yet this deficiency only affects the channel
|
// |buildTCPReceiverTransport|. Yet this deficiency only affects the channel
|
||||||
// description for the answer, which is not actually checked at requester side.
|
// description for the answer, which is not actually checked at requester side.
|
||||||
nsCOMPtr<nsINetAddr> selfAddr;
|
nsCOMPtr<nsINetAddr> selfAddr;
|
||||||
nsresult rv = mTransport->GetSelfAddress(getter_AddRefs(selfAddr));
|
rv = mTransport->GetSelfAddress(getter_AddRefs(selfAddr));
|
||||||
NS_WARN_IF(NS_FAILED(rv));
|
NS_WARN_IF(NS_FAILED(rv));
|
||||||
|
|
||||||
nsCString address;
|
nsCString address;
|
||||||
|
@ -790,6 +827,9 @@ PresentationPresentingInfo::OnSessionTransport(nsIPresentationSessionTransport*
|
||||||
return mControlChannel->SendAnswer(description);
|
return mControlChannel->SendAnswer(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PresentationPresentingInfo::OnError(nsresult reason)
|
PresentationPresentingInfo::OnError(nsresult reason)
|
||||||
{
|
{
|
||||||
|
@ -799,6 +839,13 @@ PresentationPresentingInfo::OnError(nsresult reason)
|
||||||
nsresult
|
nsresult
|
||||||
PresentationPresentingInfo::InitTransportAndSendAnswer()
|
PresentationPresentingInfo::InitTransportAndSendAnswer()
|
||||||
{
|
{
|
||||||
|
uint8_t type = 0;
|
||||||
|
nsresult rv = mRequesterDescription->GetType(&type);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == nsIPresentationChannelDescription::TYPE_TCP) {
|
||||||
// Establish a data transport channel |mTransport| to the sender and use
|
// Establish a data transport channel |mTransport| to the sender and use
|
||||||
// |this| as the callback.
|
// |this| as the callback.
|
||||||
nsCOMPtr<nsIPresentationTCPSessionTransportBuilder> builder =
|
nsCOMPtr<nsIPresentationTCPSessionTransportBuilder> builder =
|
||||||
|
@ -807,9 +854,43 @@ PresentationPresentingInfo::InitTransportAndSendAnswer()
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mBuilder = builder;
|
||||||
|
mTransportType = nsIPresentationChannelDescription::TYPE_TCP;
|
||||||
return builder->BuildTCPReceiverTransport(mRequesterDescription, this);
|
return builder->BuildTCPReceiverTransport(mRequesterDescription, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == nsIPresentationChannelDescription::TYPE_DATACHANNEL) {
|
||||||
|
nsCOMPtr<nsIPresentationDataChannelSessionTransportBuilder> builder =
|
||||||
|
do_CreateInstance("@mozilla.org/presentation/datachanneltransportbuilder;1");
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!builder)) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mBuilder = builder;
|
||||||
|
mTransportType = nsIPresentationChannelDescription::TYPE_DATACHANNEL;
|
||||||
|
rv = builder->BuildDataChannelTransport(nsIPresentationSessionTransportBuilder::TYPE_RECEIVER,
|
||||||
|
GetWindow(),
|
||||||
|
mControlChannel,
|
||||||
|
this);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delegate |onOffer| to builder
|
||||||
|
nsCOMPtr<nsIPresentationControlChannelListener> listener(do_QueryInterface(builder));
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!listener)) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return listener->OnOffer(mRequesterDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(false, "Unknown nsIPresentationChannelDescription type!");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PresentationPresentingInfo::UntrackFromService()
|
PresentationPresentingInfo::UntrackFromService()
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,10 +111,7 @@ protected:
|
||||||
|
|
||||||
nsresult ReplySuccess();
|
nsresult ReplySuccess();
|
||||||
|
|
||||||
bool IsSessionReady()
|
virtual bool IsSessionReady() = 0;
|
||||||
{
|
|
||||||
return mIsResponderReady && mIsTransportReady;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual nsresult UntrackFromService();
|
virtual nsresult UntrackFromService();
|
||||||
|
|
||||||
|
@ -133,6 +130,11 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should be nsIPresentationChannelDescription::TYPE_TCP/TYPE_DATACHANNEL
|
||||||
|
uint8_t mTransportType = 0;
|
||||||
|
|
||||||
|
nsPIDOMWindowInner* GetWindow();
|
||||||
|
|
||||||
nsString mUrl;
|
nsString mUrl;
|
||||||
nsString mSessionId;
|
nsString mSessionId;
|
||||||
bool mIsResponderReady;
|
bool mIsResponderReady;
|
||||||
|
@ -143,6 +145,7 @@ protected:
|
||||||
nsCOMPtr<nsIPresentationDevice> mDevice;
|
nsCOMPtr<nsIPresentationDevice> mDevice;
|
||||||
nsCOMPtr<nsIPresentationSessionTransport> mTransport;
|
nsCOMPtr<nsIPresentationSessionTransport> mTransport;
|
||||||
nsCOMPtr<nsIPresentationControlChannel> mControlChannel;
|
nsCOMPtr<nsIPresentationControlChannel> mControlChannel;
|
||||||
|
nsCOMPtr<nsIPresentationSessionTransportBuilder> mBuilder;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Session info with controlling browsing context (sender side) behaviors.
|
// Session info with controlling browsing context (sender side) behaviors.
|
||||||
|
@ -177,6 +180,18 @@ private:
|
||||||
nsresult OnGetAddress(const nsACString& aAddress);
|
nsresult OnGetAddress(const nsACString& aAddress);
|
||||||
|
|
||||||
nsCOMPtr<nsIServerSocket> mServerSocket;
|
nsCOMPtr<nsIServerSocket> mServerSocket;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool IsSessionReady() override
|
||||||
|
{
|
||||||
|
if (mTransportType == nsIPresentationChannelDescription::TYPE_TCP) {
|
||||||
|
return mIsResponderReady && mIsTransportReady;
|
||||||
|
} else if (mTransportType == nsIPresentationChannelDescription::TYPE_DATACHANNEL) {
|
||||||
|
// Established RTCDataChannel implies responder is ready.
|
||||||
|
return mIsTransportReady;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Session info with presenting browsing context (receiver side) behaviors.
|
// Session info with presenting browsing context (receiver side) behaviors.
|
||||||
|
@ -236,6 +251,12 @@ private:
|
||||||
// The content parent communicating with the content process which the OOP
|
// The content parent communicating with the content process which the OOP
|
||||||
// receiver page belongs to.
|
// receiver page belongs to.
|
||||||
nsCOMPtr<nsIContentParent> mContentParent;
|
nsCOMPtr<nsIContentParent> mContentParent;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool IsSessionReady() override
|
||||||
|
{
|
||||||
|
return mIsResponderReady && mIsTransportReady;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -151,11 +151,9 @@ PresentationTCPSessionTransport::BuildTCPReceiverTransport(nsIPresentationChanne
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO bug 1148307 Implement PresentationSessionTransport with DataChannel.
|
// TODO bug 1228504 Take all IP addresses in PresentationChannelDescription
|
||||||
// Ultimately we may use all the available addresses. DataChannel appears
|
// into account. And at the first stage Presentation API is only exposed on
|
||||||
// more robust upon handling ICE. And at the first stage Presentation API is
|
// Firefox OS where the first IP appears enough for most scenarios.
|
||||||
// only exposed on Firefox OS where the first IP appears enough for most
|
|
||||||
// scenarios.
|
|
||||||
nsCOMPtr<nsISupportsCString> supportStr = do_QueryElementAt(serverHosts, 0);
|
nsCOMPtr<nsISupportsCString> supportStr = do_QueryElementAt(serverHosts, 0);
|
||||||
if (NS_WARN_IF(!supportStr)) {
|
if (NS_WARN_IF(!supportStr)) {
|
||||||
return NS_ERROR_INVALID_ARG;
|
return NS_ERROR_INVALID_ARG;
|
||||||
|
|
|
@ -33,11 +33,6 @@ namespace dom {
|
||||||
* presenting receiver side. The lifetime is managed in either
|
* presenting receiver side. The lifetime is managed in either
|
||||||
* |PresentationControllingInfo| (sender side) or |PresentationPresentingInfo|
|
* |PresentationControllingInfo| (sender side) or |PresentationPresentingInfo|
|
||||||
* (receiver side) in PresentationSessionInfo.cpp.
|
* (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 PresentationTCPSessionTransport final : public nsIPresentationSessionTransport
|
class PresentationTCPSessionTransport final : public nsIPresentationSessionTransport
|
||||||
, public nsIPresentationTCPSessionTransportBuilder
|
, public nsIPresentationTCPSessionTransportBuilder
|
||||||
|
|
|
@ -39,6 +39,6 @@ interface nsIPresentationRespondingListener : nsISupports
|
||||||
/*
|
/*
|
||||||
* Called when an incoming session connects.
|
* Called when an incoming session connects.
|
||||||
*/
|
*/
|
||||||
void notifySessionConnect(in uint64_t windowId,
|
void notifySessionConnect(in unsigned long long windowId,
|
||||||
in DOMString sessionId);
|
in DOMString sessionId);
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,7 @@ interface nsIPresentationServiceCallback : nsISupports
|
||||||
void notifyError(in nsresult error);
|
void notifyError(in nsresult error);
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, uuid(61864149-9838-4aa1-a21a-63eaf0b84a8c)]
|
[scriptable, uuid(de42b741-5619-4650-b961-c2cebb572c95)]
|
||||||
interface nsIPresentationService : nsISupports
|
interface nsIPresentationService : nsISupports
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -45,6 +45,10 @@ interface nsIPresentationService : nsISupports
|
||||||
* @param origin: The url of requesting page.
|
* @param origin: The url of requesting page.
|
||||||
* @param deviceId: The specified device of handling this request, null string
|
* @param deviceId: The specified device of handling this request, null string
|
||||||
for prompt device selection dialog.
|
for prompt device selection dialog.
|
||||||
|
* @param windowId: The inner window ID associated with the presentation
|
||||||
|
* session. (0 implies no window ID since no actual window
|
||||||
|
* uses 0 as its ID. Generally it's the case the window is
|
||||||
|
* located in different process from this service)
|
||||||
* @param callback: Invoke the callback when the operation is completed.
|
* @param callback: Invoke the callback when the operation is completed.
|
||||||
* NotifySuccess() is called with |id| if a session is
|
* NotifySuccess() is called with |id| if a session is
|
||||||
* established successfully with the selected device.
|
* established successfully with the selected device.
|
||||||
|
@ -54,6 +58,7 @@ interface nsIPresentationService : nsISupports
|
||||||
in DOMString sessionId,
|
in DOMString sessionId,
|
||||||
in DOMString origin,
|
in DOMString origin,
|
||||||
in DOMString deviceId,
|
in DOMString deviceId,
|
||||||
|
in unsigned long long windowId,
|
||||||
in nsIPresentationServiceCallback callback);
|
in nsIPresentationServiceCallback callback);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -114,14 +119,14 @@ interface nsIPresentationService : nsISupports
|
||||||
* @param windowId: The window ID associated with the listener.
|
* @param windowId: The window ID associated with the listener.
|
||||||
* @param listener: The listener to register.
|
* @param listener: The listener to register.
|
||||||
*/
|
*/
|
||||||
void registerRespondingListener(in uint64_t windowId,
|
void registerRespondingListener(in unsigned long long windowId,
|
||||||
in nsIPresentationRespondingListener listener);
|
in nsIPresentationRespondingListener listener);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unregister a responding listener. Must be called from the main thread.
|
* Unregister a responding listener. Must be called from the main thread.
|
||||||
* @param windowId: The window ID associated with the listener.
|
* @param windowId: The window ID associated with the listener.
|
||||||
*/
|
*/
|
||||||
void unregisterRespondingListener(in uint64_t windowId);
|
void unregisterRespondingListener(in unsigned long long windowId);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the presentation instance has an existent session ID at launch.
|
* Check if the presentation instance has an existent session ID at launch.
|
||||||
|
@ -131,7 +136,7 @@ interface nsIPresentationService : nsISupports
|
||||||
*
|
*
|
||||||
* @param windowId: The inner window ID used to look up the session ID.
|
* @param windowId: The inner window ID used to look up the session ID.
|
||||||
*/
|
*/
|
||||||
DOMString getExistentSessionIdAtLaunch(in uint64_t windowId);
|
DOMString getExistentSessionIdAtLaunch(in unsigned long long windowId);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notify the receiver page is ready for presentation use.
|
* Notify the receiver page is ready for presentation use.
|
||||||
|
@ -139,10 +144,11 @@ interface nsIPresentationService : nsISupports
|
||||||
* @param sessionId: An ID to identify presentation session.
|
* @param sessionId: An ID to identify presentation session.
|
||||||
* @param windowId: The inner window ID associated with the presentation
|
* @param windowId: The inner window ID associated with the presentation
|
||||||
* session. (0 implies no window ID since no actual window
|
* session. (0 implies no window ID since no actual window
|
||||||
* uses 0 as its ID.)
|
* uses 0 as its ID. Generally it's the case the window is
|
||||||
|
* located in different process from this service)
|
||||||
*/
|
*/
|
||||||
void notifyReceiverReady(in DOMString sessionId,
|
void notifyReceiverReady(in DOMString sessionId,
|
||||||
[optional] in uint64_t windowId);
|
[optional] in unsigned long long windowId);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Untrack the relevant info about the presentation session if there's any.
|
* Untrack the relevant info about the presentation session if there's any.
|
||||||
|
@ -150,4 +156,9 @@ interface nsIPresentationService : nsISupports
|
||||||
* @param sessionId: An ID to identify presentation session.
|
* @param sessionId: An ID to identify presentation session.
|
||||||
*/
|
*/
|
||||||
void untrackSessionInfo(in DOMString sessionId);
|
void untrackSessionInfo(in DOMString sessionId);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The windowId for building RTCDataChannel session transport
|
||||||
|
*/
|
||||||
|
unsigned long long getWindowIdBySessionId(in DOMString sessionId);
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
interface nsIPresentationChannelDescription;
|
interface nsIPresentationChannelDescription;
|
||||||
interface nsISocketTransport;
|
interface nsISocketTransport;
|
||||||
interface nsIDOMWindow;
|
interface mozIDOMWindow;
|
||||||
interface nsIPresentationControlChannel;
|
interface nsIPresentationControlChannel;
|
||||||
interface nsIPresentationSessionTransport;
|
interface nsIPresentationSessionTransport;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ interface nsIPresentationDataChannelSessionTransportBuilder : nsIPresentationSes
|
||||||
* |buildDataChannelTransport|.
|
* |buildDataChannelTransport|.
|
||||||
*/
|
*/
|
||||||
void buildDataChannelTransport(in uint8_t aType,
|
void buildDataChannelTransport(in uint8_t aType,
|
||||||
in nsIDOMWindow aWindow,
|
in mozIDOMWindow aWindow,
|
||||||
in nsIPresentationControlChannel aControlChannel,
|
in nsIPresentationControlChannel aControlChannel,
|
||||||
in nsIPresentationSessionTransportBuilderListener aListener);
|
in nsIPresentationSessionTransportBuilderListener aListener);
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,12 +50,18 @@ PresentationIPCService::StartSession(const nsAString& aUrl,
|
||||||
const nsAString& aSessionId,
|
const nsAString& aSessionId,
|
||||||
const nsAString& aOrigin,
|
const nsAString& aOrigin,
|
||||||
const nsAString& aDeviceId,
|
const nsAString& aDeviceId,
|
||||||
|
uint64_t aWindowId,
|
||||||
nsIPresentationServiceCallback* aCallback)
|
nsIPresentationServiceCallback* aCallback)
|
||||||
{
|
{
|
||||||
return SendRequest(aCallback, StartSessionRequest(nsAutoString(aUrl),
|
if (aWindowId != 0) {
|
||||||
nsAutoString(aSessionId),
|
mRespondingSessionIds.Put(aWindowId, new nsString(aSessionId));
|
||||||
nsAutoString(aOrigin),
|
mRespondingWindowIds.Put(aSessionId, aWindowId);
|
||||||
nsAutoString(aDeviceId)));
|
}
|
||||||
|
|
||||||
|
return SendRequest(aCallback, StartSessionRequest(nsString(aUrl),
|
||||||
|
nsString(aSessionId),
|
||||||
|
nsString(aOrigin),
|
||||||
|
nsString(aDeviceId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -65,8 +71,8 @@ PresentationIPCService::SendSessionMessage(const nsAString& aSessionId,
|
||||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||||
MOZ_ASSERT(!aData.IsEmpty());
|
MOZ_ASSERT(!aData.IsEmpty());
|
||||||
|
|
||||||
return SendRequest(nullptr, SendSessionMessageRequest(nsAutoString(aSessionId),
|
return SendRequest(nullptr, SendSessionMessageRequest(nsString(aSessionId),
|
||||||
nsAutoString(aData)));
|
nsString(aData)));
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -74,7 +80,7 @@ PresentationIPCService::CloseSession(const nsAString& aSessionId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||||
|
|
||||||
return SendRequest(nullptr, CloseSessionRequest(nsAutoString(aSessionId)));
|
return SendRequest(nullptr, CloseSessionRequest(nsString(aSessionId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -82,7 +88,7 @@ PresentationIPCService::TerminateSession(const nsAString& aSessionId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||||
|
|
||||||
return SendRequest(nullptr, TerminateSessionRequest(nsAutoString(aSessionId)));
|
return SendRequest(nullptr, TerminateSessionRequest(nsString(aSessionId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -131,7 +137,7 @@ PresentationIPCService::RegisterSessionListener(const nsAString& aSessionId,
|
||||||
|
|
||||||
mSessionListeners.Put(aSessionId, aListener);
|
mSessionListeners.Put(aSessionId, aListener);
|
||||||
if (sPresentationChild) {
|
if (sPresentationChild) {
|
||||||
NS_WARN_IF(!sPresentationChild->SendRegisterSessionHandler(nsAutoString(aSessionId)));
|
NS_WARN_IF(!sPresentationChild->SendRegisterSessionHandler(nsString(aSessionId)));
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +151,7 @@ PresentationIPCService::UnregisterSessionListener(const nsAString& aSessionId)
|
||||||
|
|
||||||
mSessionListeners.Remove(aSessionId);
|
mSessionListeners.Remove(aSessionId);
|
||||||
if (sPresentationChild) {
|
if (sPresentationChild) {
|
||||||
NS_WARN_IF(!sPresentationChild->SendUnregisterSessionHandler(nsAutoString(aSessionId)));
|
NS_WARN_IF(!sPresentationChild->SendUnregisterSessionHandler(nsString(aSessionId)));
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +181,16 @@ PresentationIPCService::UnregisterRespondingListener(uint64_t aWindowId)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
PresentationIPCService::GetWindowIdBySessionId(const nsAString& aSessionId,
|
||||||
|
uint64_t* aWindowId)
|
||||||
|
{
|
||||||
|
if (mRespondingWindowIds.Get(aSessionId, aWindowId)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PresentationIPCService::NotifySessionStateChange(const nsAString& aSessionId,
|
PresentationIPCService::NotifySessionStateChange(const nsAString& aSessionId,
|
||||||
uint16_t aState)
|
uint16_t aState)
|
||||||
|
@ -250,10 +266,10 @@ PresentationIPCService::NotifyReceiverReady(const nsAString& aSessionId,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track the responding info for an OOP receiver page.
|
// Track the responding info for an OOP receiver page.
|
||||||
mRespondingSessionIds.Put(aWindowId, new nsAutoString(aSessionId));
|
mRespondingSessionIds.Put(aWindowId, new nsString(aSessionId));
|
||||||
mRespondingWindowIds.Put(aSessionId, aWindowId);
|
mRespondingWindowIds.Put(aSessionId, aWindowId);
|
||||||
|
|
||||||
NS_WARN_IF(!sPresentationChild->SendNotifyReceiverReady(nsAutoString(aSessionId)));
|
NS_WARN_IF(!sPresentationChild->SendNotifyReceiverReady(nsString(aSessionId)));
|
||||||
|
|
||||||
// Release mCallback after using aSessionId
|
// Release mCallback after using aSessionId
|
||||||
// because aSessionId is held by mCallback.
|
// because aSessionId is held by mCallback.
|
||||||
|
|
|
@ -186,7 +186,7 @@ PresentationParent::NotifyStateChange(const nsAString& aSessionId,
|
||||||
uint16_t aState)
|
uint16_t aState)
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(mActorDestroyed ||
|
if (NS_WARN_IF(mActorDestroyed ||
|
||||||
!SendNotifySessionStateChange(nsAutoString(aSessionId), aState))) {
|
!SendNotifySessionStateChange(nsString(aSessionId), aState))) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -197,7 +197,7 @@ PresentationParent::NotifyMessage(const nsAString& aSessionId,
|
||||||
const nsACString& aData)
|
const nsACString& aData)
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(mActorDestroyed ||
|
if (NS_WARN_IF(mActorDestroyed ||
|
||||||
!SendNotifyMessage(nsAutoString(aSessionId), nsAutoCString(aData)))) {
|
!SendNotifyMessage(nsString(aSessionId), nsCString(aData)))) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -208,7 +208,7 @@ PresentationParent::NotifySessionConnect(uint64_t aWindowId,
|
||||||
const nsAString& aSessionId)
|
const nsAString& aSessionId)
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(mActorDestroyed ||
|
if (NS_WARN_IF(mActorDestroyed ||
|
||||||
!SendNotifySessionConnect(aWindowId, nsAutoString(aSessionId)))) {
|
!SendNotifySessionConnect(aWindowId, nsString(aSessionId)))) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -218,6 +218,8 @@ bool
|
||||||
PresentationParent::RecvNotifyReceiverReady(const nsString& aSessionId)
|
PresentationParent::RecvNotifyReceiverReady(const nsString& aSessionId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mService);
|
MOZ_ASSERT(mService);
|
||||||
|
|
||||||
|
// Set window ID to 0 since the window is from content process.
|
||||||
NS_WARN_IF(NS_FAILED(mService->NotifyReceiverReady(aSessionId, 0)));
|
NS_WARN_IF(NS_FAILED(mService->NotifyReceiverReady(aSessionId, 0)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -251,8 +253,10 @@ nsresult
|
||||||
PresentationRequestParent::DoRequest(const StartSessionRequest& aRequest)
|
PresentationRequestParent::DoRequest(const StartSessionRequest& aRequest)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mService);
|
MOZ_ASSERT(mService);
|
||||||
|
|
||||||
|
// Set window ID to 0 since the window is from content process.
|
||||||
return mService->StartSession(aRequest.url(), aRequest.sessionId(),
|
return mService->StartSession(aRequest.url(), aRequest.sessionId(),
|
||||||
aRequest.origin(), aRequest.deviceId(), this);
|
aRequest.origin(), aRequest.deviceId(), 0, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -65,6 +65,10 @@ IPDL_SOURCES += [
|
||||||
'ipc/PPresentationRequest.ipdl'
|
'ipc/PPresentationRequest.ipdl'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
LOCAL_INCLUDES += [
|
||||||
|
'../base'
|
||||||
|
]
|
||||||
|
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components;
|
const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components;
|
||||||
|
|
||||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||||
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
|
Cu.import('resource://gre/modules/Timer.jsm');
|
||||||
|
|
||||||
function registerMockedFactory(contractId, mockedClassId, mockedFactory) {
|
function registerMockedFactory(contractId, mockedClassId, mockedFactory) {
|
||||||
var originalClassId, originalFactory;
|
var originalClassId, originalFactory;
|
||||||
|
@ -49,7 +51,12 @@ addresses.appendElement(address, false);
|
||||||
|
|
||||||
const mockedChannelDescription = {
|
const mockedChannelDescription = {
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]),
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]),
|
||||||
type: 1,
|
get type() {
|
||||||
|
if (Services.prefs.getBoolPref("dom.presentation.session_transport.data_channel.enable")) {
|
||||||
|
return Ci.nsIPresentationChannelDescription.TYPE_DATACHANNEL;
|
||||||
|
}
|
||||||
|
return Ci.nsIPresentationChannelDescription.TYPE_TCP;
|
||||||
|
},
|
||||||
tcpAddress: addresses,
|
tcpAddress: addresses,
|
||||||
tcpPort: 1234,
|
tcpPort: 1234,
|
||||||
};
|
};
|
||||||
|
@ -199,6 +206,8 @@ const mockedDevicePrompt = {
|
||||||
const mockedSessionTransport = {
|
const mockedSessionTransport = {
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransport,
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransport,
|
||||||
Ci.nsIPresentationTCPSessionTransportBuilder,
|
Ci.nsIPresentationTCPSessionTransportBuilder,
|
||||||
|
Ci.nsIPresentationDataChannelSessionTransportBuilder,
|
||||||
|
Ci.nsIPresentationControlChannelListener,
|
||||||
Ci.nsIFactory]),
|
Ci.nsIFactory]),
|
||||||
createInstance: function(aOuter, aIID) {
|
createInstance: function(aOuter, aIID) {
|
||||||
if (aOuter) {
|
if (aOuter) {
|
||||||
|
@ -220,10 +229,11 @@ const mockedSessionTransport = {
|
||||||
this._listener = listener;
|
this._listener = listener;
|
||||||
this._type = Ci.nsIPresentationSessionTransportBuilder.TYPE_SENDER;
|
this._type = Ci.nsIPresentationSessionTransportBuilder.TYPE_SENDER;
|
||||||
|
|
||||||
|
setTimeout(()=>{
|
||||||
this._listener.onSessionTransport(this);
|
this._listener.onSessionTransport(this);
|
||||||
this._listener = null;
|
this._listener = null;
|
||||||
|
|
||||||
this.simulateTransportReady();
|
this.simulateTransportReady();
|
||||||
|
}, 0);
|
||||||
},
|
},
|
||||||
buildTCPReceiverTransport: function(description, listener) {
|
buildTCPReceiverTransport: function(description, listener) {
|
||||||
this._listener = listener;
|
this._listener = listener;
|
||||||
|
@ -237,8 +247,25 @@ const mockedSessionTransport = {
|
||||||
port: description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpPort,
|
port: description.QueryInterface(Ci.nsIPresentationChannelDescription).tcpPort,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setTimeout(()=>{
|
||||||
this._listener.onSessionTransport(this);
|
this._listener.onSessionTransport(this);
|
||||||
this._listener = null;
|
this._listener = null;
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
// in-process case
|
||||||
|
buildDataChannelTransport: function(type, window, controlChannel, listener) {
|
||||||
|
dump("build data channel transport\n");
|
||||||
|
this._listener = listener;
|
||||||
|
this._type = type;
|
||||||
|
|
||||||
|
var hasNavigator = window ? (typeof window.navigator != "undefined") : false;
|
||||||
|
sendAsyncMessage('check-navigator', hasNavigator);
|
||||||
|
|
||||||
|
setTimeout(()=>{
|
||||||
|
this._listener.onSessionTransport(this);
|
||||||
|
this._listener = null;
|
||||||
|
this.simulateTransportReady();
|
||||||
|
}, 0);
|
||||||
},
|
},
|
||||||
enableDataNotification: function() {
|
enableDataNotification: function() {
|
||||||
sendAsyncMessage('data-transport-notification-enabled');
|
sendAsyncMessage('data-transport-notification-enabled');
|
||||||
|
@ -256,6 +283,10 @@ const mockedSessionTransport = {
|
||||||
simulateIncomingMessage: function(message) {
|
simulateIncomingMessage: function(message) {
|
||||||
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyData(message);
|
this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyData(message);
|
||||||
},
|
},
|
||||||
|
onOffer: function(aOffer) {
|
||||||
|
},
|
||||||
|
onAnswer: function(aAnswer) {
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockedNetworkInfo = {
|
const mockedNetworkInfo = {
|
||||||
|
@ -311,6 +342,9 @@ originalFactoryData.push(registerMockedFactory("@mozilla.org/network/server-sock
|
||||||
originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/presentationtcpsessiontransport;1",
|
originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/presentationtcpsessiontransport;1",
|
||||||
uuidGenerator.generateUUID(),
|
uuidGenerator.generateUUID(),
|
||||||
mockedSessionTransport));
|
mockedSessionTransport));
|
||||||
|
originalFactoryData.push(registerMockedFactory("@mozilla.org/presentation/datachanneltransportbuilder;1",
|
||||||
|
uuidGenerator.generateUUID(),
|
||||||
|
mockedSessionTransport));
|
||||||
originalFactoryData.push(registerMockedFactory("@mozilla.org/network/manager;1",
|
originalFactoryData.push(registerMockedFactory("@mozilla.org/network/manager;1",
|
||||||
uuidGenerator.generateUUID(),
|
uuidGenerator.generateUUID(),
|
||||||
mockedNetworkManager));
|
mockedNetworkManager));
|
||||||
|
|
|
@ -9,23 +9,28 @@ support-files =
|
||||||
file_presentation_receiver_inner_iframe_oop.html
|
file_presentation_receiver_inner_iframe_oop.html
|
||||||
file_presentation_non_receiver_inner_iframe_oop.html
|
file_presentation_non_receiver_inner_iframe_oop.html
|
||||||
|
|
||||||
|
|
||||||
|
[test_presentation_dc_sender.html]
|
||||||
|
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||||
|
[test_presentation_dc_receiver.html]
|
||||||
|
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||||
[test_presentation_device_info.html]
|
[test_presentation_device_info.html]
|
||||||
[test_presentation_device_info_permission.html]
|
[test_presentation_device_info_permission.html]
|
||||||
[test_presentation_sender_disconnect.html]
|
|
||||||
skip-if = toolkit == 'android' # Bug 1129785
|
|
||||||
[test_presentation_sender_establish_connection_error.html]
|
|
||||||
skip-if = toolkit == 'android' # Bug 1129785
|
|
||||||
[test_presentation_sender.html]
|
|
||||||
skip-if = toolkit == 'android' # Bug 1129785
|
|
||||||
[test_presentation_sender_default_request.html]
|
|
||||||
skip-if = toolkit == 'android' # Bug 1129785
|
|
||||||
[test_presentation_sender_startWithDevice.html]
|
[test_presentation_sender_startWithDevice.html]
|
||||||
skip-if = toolkit == 'android' # Bug 1129785
|
skip-if = toolkit == 'android' # Bug 1129785
|
||||||
[test_presentation_receiver_establish_connection_error.html]
|
[test_presentation_tcp_sender_disconnect.html]
|
||||||
|
skip-if = toolkit == 'android' # Bug 1129785
|
||||||
|
[test_presentation_tcp_sender_establish_connection_error.html]
|
||||||
|
skip-if = toolkit == 'android' # Bug 1129785
|
||||||
|
[test_presentation_tcp_sender.html]
|
||||||
|
skip-if = toolkit == 'android' # Bug 1129785
|
||||||
|
[test_presentation_tcp_sender_default_request.html]
|
||||||
|
skip-if = toolkit == 'android' # Bug 1129785
|
||||||
|
[test_presentation_tcp_receiver_establish_connection_error.html]
|
||||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android' || os == 'mac' || os == 'win' || buildapp == 'mulet') # Bug 1129785, Bug 1204709
|
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android' || os == 'mac' || os == 'win' || buildapp == 'mulet') # Bug 1129785, Bug 1204709
|
||||||
[test_presentation_receiver_establish_connection_timeout.html]
|
[test_presentation_tcp_receiver_establish_connection_timeout.html]
|
||||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||||
[test_presentation_receiver.html]
|
[test_presentation_tcp_receiver.html]
|
||||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||||
[test_presentation_receiver_oop.html]
|
[test_presentation_tcp_receiver_oop.html]
|
||||||
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!-- Any copyright is dedicated to the Public Domain.
|
||||||
|
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for B2G PresentationConnection API at receiver side</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1148307">Test for B2G PresentationConnection API at receiver side</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test"></pre>
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
|
||||||
|
var receiverUrl = SimpleTest.getTestFileURL('file_presentation_receiver.html');
|
||||||
|
|
||||||
|
var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
|
||||||
|
.getService(SpecialPowers.Ci.nsIObserverService);
|
||||||
|
|
||||||
|
function setup() {
|
||||||
|
return new Promise(function(aResolve, aReject) {
|
||||||
|
gScript.sendAsyncMessage('trigger-device-add');
|
||||||
|
|
||||||
|
var iframe = document.createElement('iframe');
|
||||||
|
iframe.setAttribute('src', receiverUrl);
|
||||||
|
|
||||||
|
// This event is triggered when the iframe calls "postMessage".
|
||||||
|
window.addEventListener('message', function listener(aEvent) {
|
||||||
|
var message = aEvent.data;
|
||||||
|
if (/^OK /.exec(message)) {
|
||||||
|
ok(true, "Message from iframe: " + message);
|
||||||
|
} else if (/^KO /.exec(message)) {
|
||||||
|
ok(false, "Message from iframe: " + message);
|
||||||
|
} else if (/^INFO /.exec(message)) {
|
||||||
|
info("Message from iframe: " + message);
|
||||||
|
} else if (/^COMMAND /.exec(message)) {
|
||||||
|
var command = JSON.parse(message.replace(/^COMMAND /, ''));
|
||||||
|
gScript.sendAsyncMessage(command.name, command.data);
|
||||||
|
} else if (/^DONE$/.exec(message)) {
|
||||||
|
ok(true, "Messaging from iframe complete.");
|
||||||
|
window.removeEventListener('message', listener);
|
||||||
|
|
||||||
|
teardown();
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
var promise = new Promise(function(aResolve, aReject) {
|
||||||
|
document.body.appendChild(iframe);
|
||||||
|
|
||||||
|
aResolve(iframe);
|
||||||
|
});
|
||||||
|
obs.notifyObservers(promise, 'setup-request-promise', null);
|
||||||
|
|
||||||
|
gScript.addMessageListener('offer-received', function offerReceivedHandler() {
|
||||||
|
gScript.removeMessageListener('offer-received', offerReceivedHandler);
|
||||||
|
info("An offer is received.");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('answer-sent', function answerSentHandler(aIsValid) {
|
||||||
|
gScript.removeMessageListener('answer-sent', answerSentHandler);
|
||||||
|
ok(aIsValid, "A valid answer is sent.");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
|
||||||
|
gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
|
||||||
|
is(aReason, SpecialPowers.Cr.NS_OK, "The control channel is closed normally.");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('check-navigator', function checknavigatorHandler(aSuccess) {
|
||||||
|
gScript.removeMessageListener('check-navigator', checknavigatorHandler);
|
||||||
|
ok(aSuccess, "buildDataChannel get correct window object");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('data-transport-notification-enabled', function dataTransportNotificationEnabledHandler() {
|
||||||
|
gScript.removeMessageListener('data-transport-notification-enabled', dataTransportNotificationEnabledHandler);
|
||||||
|
info("Data notification is enabled for data transport channel.");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('data-transport-closed', function dataTransportClosedHandler(aReason) {
|
||||||
|
gScript.removeMessageListener('data-transport-closed', dataTransportClosedHandler);
|
||||||
|
is(aReason, SpecialPowers.Cr.NS_OK, "The data transport should be closed normally.");
|
||||||
|
});
|
||||||
|
|
||||||
|
aResolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testIncomingSessionRequest() {
|
||||||
|
return new Promise(function(aResolve, aReject) {
|
||||||
|
gScript.addMessageListener('receiver-launching', function launchReceiverHandler(aSessionId) {
|
||||||
|
gScript.removeMessageListener('receiver-launching', launchReceiverHandler);
|
||||||
|
info("Trying to launch receiver page.");
|
||||||
|
|
||||||
|
ok(navigator.presentation, "navigator.presentation should be available in in-process pages.");
|
||||||
|
ok(!navigator.presentation.receiver, "Non-receiving in-process pages shouldn't get a presentation receiver instance.");
|
||||||
|
aResolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.sendAsyncMessage('trigger-incoming-session-request', receiverUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function teardown() {
|
||||||
|
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||||
|
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||||
|
gScript.destroy();
|
||||||
|
SimpleTest.finish();
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.sendAsyncMessage('teardown');
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
setup().
|
||||||
|
then(testIncomingSessionRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SpecialPowers.pushPermissions([
|
||||||
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
|
{type: 'presentation', allow: true, context: document},
|
||||||
|
], function() {
|
||||||
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
|
["dom.presentation.session_transport.data_channel.enable", true]]},
|
||||||
|
runTests);
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,208 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!-- Any copyright is dedicated to the Public Domain.
|
||||||
|
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for B2G Presentation API at sender side</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1148307">Test for B2G Presentation API at sender side</a>
|
||||||
|
<script type="application/javascript;version=1.8">
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript.js'));
|
||||||
|
var request;
|
||||||
|
var connection;
|
||||||
|
|
||||||
|
function testSetup() {
|
||||||
|
return new Promise(function(aResolve, aReject) {
|
||||||
|
request = new PresentationRequest("http://example.com");
|
||||||
|
|
||||||
|
request.getAvailability().then(
|
||||||
|
function(aAvailability) {
|
||||||
|
aAvailability.onchange = function() {
|
||||||
|
aAvailability.onchange = null;
|
||||||
|
ok(aAvailability.value, "Device should be available.");
|
||||||
|
aResolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(aError) {
|
||||||
|
ok(false, "Error occurred when getting availability: " + aError);
|
||||||
|
teardown();
|
||||||
|
aReject();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
gScript.sendAsyncMessage('trigger-device-add');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testStartConnection() {
|
||||||
|
return new Promise(function(aResolve, aReject) {
|
||||||
|
gScript.addMessageListener('device-prompt', function devicePromptHandler() {
|
||||||
|
gScript.removeMessageListener('device-prompt', devicePromptHandler);
|
||||||
|
info("Device prompt is triggered.");
|
||||||
|
gScript.sendAsyncMessage('trigger-device-prompt-select');
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
|
||||||
|
gScript.removeMessageListener('control-channel-established', controlChannelEstablishedHandler);
|
||||||
|
info("A control channel is established.");
|
||||||
|
gScript.sendAsyncMessage('trigger-control-channel-open');
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('control-channel-opened', function controlChannelOpenedHandler(aReason) {
|
||||||
|
gScript.removeMessageListener('control-channel-opened', controlChannelOpenedHandler);
|
||||||
|
info("The control channel is opened.");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('control-channel-closed', function controlChannelClosedHandler(aReason) {
|
||||||
|
gScript.removeMessageListener('control-channel-closed', controlChannelClosedHandler);
|
||||||
|
info("The control channel is closed. " + aReason);
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('check-navigator', function checknavigatorHandler(aSuccess) {
|
||||||
|
gScript.removeMessageListener('check-navigator', checknavigatorHandler);
|
||||||
|
ok(aSuccess, "buildDataChannel get correct window object");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('offer-sent', function offerSentHandler(aIsValid) {
|
||||||
|
gScript.removeMessageListener('offer-sent', offerSentHandler);
|
||||||
|
ok(aIsValid, "A valid offer is sent out.");
|
||||||
|
gScript.sendAsyncMessage('trigger-incoming-transport');
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('answer-received', function answerReceivedHandler() {
|
||||||
|
gScript.removeMessageListener('answer-received', answerReceivedHandler);
|
||||||
|
info("An answer is received.");
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('data-transport-initialized', function dataTransportInitializedHandler() {
|
||||||
|
gScript.removeMessageListener('data-transport-initialized', dataTransportInitializedHandler);
|
||||||
|
info("Data transport channel is initialized.");
|
||||||
|
gScript.sendAsyncMessage('trigger-incoming-answer');
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.addMessageListener('data-transport-notification-enabled', function dataTransportNotificationEnabledHandler() {
|
||||||
|
gScript.removeMessageListener('data-transport-notification-enabled', dataTransportNotificationEnabledHandler);
|
||||||
|
info("Data notification is enabled for data transport channel.");
|
||||||
|
});
|
||||||
|
|
||||||
|
var connectionFromEvent;
|
||||||
|
request.onconnectionavailable = function(aEvent) {
|
||||||
|
request.onconnectionavailable = null;
|
||||||
|
connectionFromEvent = aEvent.connection;
|
||||||
|
ok(connectionFromEvent, "|connectionavailable| event is fired with a connection.");
|
||||||
|
|
||||||
|
if (connection) {
|
||||||
|
is(connection, connectionFromEvent, "The connection from promise and the one from |connectionavailable| event should be the same.");
|
||||||
|
aResolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
request.start().then(
|
||||||
|
function(aConnection) {
|
||||||
|
connection = aConnection;
|
||||||
|
ok(connection, "Connection should be available.");
|
||||||
|
ok(connection.id, "Connection ID should be set.");
|
||||||
|
is(connection.state, "connected", "Connection state at sender side should be connected by default.");
|
||||||
|
|
||||||
|
if (connectionFromEvent) {
|
||||||
|
is(connection, connectionFromEvent, "The connection from promise and the one from |connectionavailable| event should be the same.");
|
||||||
|
aResolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(aError) {
|
||||||
|
ok(false, "Error occurred when establishing a connection: " + aError);
|
||||||
|
teardown();
|
||||||
|
aReject();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSend() {
|
||||||
|
return new Promise(function(aResolve, aReject) {
|
||||||
|
const outgoingMessage = "test outgoing message";
|
||||||
|
|
||||||
|
gScript.addMessageListener('message-sent', function messageSentHandler(aMessage) {
|
||||||
|
gScript.removeMessageListener('message-sent', messageSentHandler);
|
||||||
|
is(aMessage, outgoingMessage, "The message is sent out.");
|
||||||
|
aResolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.send(outgoingMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testIncomingMessage() {
|
||||||
|
return new Promise(function(aResolve, aReject) {
|
||||||
|
const incomingMessage = "test incoming message";
|
||||||
|
|
||||||
|
connection.addEventListener('message', function messageHandler(aEvent) {
|
||||||
|
connection.removeEventListener('message', messageHandler);
|
||||||
|
is(aEvent.data, incomingMessage, "An incoming message should be received.");
|
||||||
|
aResolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.sendAsyncMessage('trigger-incoming-message', incomingMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTerminateConnection() {
|
||||||
|
return new Promise(function(aResolve, aReject) {
|
||||||
|
gScript.addMessageListener('data-transport-closed', function dataTransportClosedHandler(aReason) {
|
||||||
|
gScript.removeMessageListener('data-transport-closed', dataTransportClosedHandler);
|
||||||
|
info("The data transport is closed. " + aReason);
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.onstatechange = function() {
|
||||||
|
connection.onstatechange = null;
|
||||||
|
is(connection.state, "terminated", "Connection should be terminated.");
|
||||||
|
aResolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
connection.terminate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function teardown() {
|
||||||
|
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
|
||||||
|
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
|
||||||
|
gScript.destroy();
|
||||||
|
info('teardown-complete');
|
||||||
|
SimpleTest.finish();
|
||||||
|
});
|
||||||
|
|
||||||
|
gScript.sendAsyncMessage('teardown');
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
ok(window.PresentationRequest, "PresentationRequest should be available.");
|
||||||
|
|
||||||
|
testSetup().
|
||||||
|
then(testStartConnection).
|
||||||
|
then(testSend).
|
||||||
|
then(testIncomingMessage).
|
||||||
|
then(testTerminateConnection).
|
||||||
|
then(teardown);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.expectAssertions(0, 5);
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SpecialPowers.pushPermissions([
|
||||||
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
|
{type: 'presentation', allow: true, context: document},
|
||||||
|
], function() {
|
||||||
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
|
["dom.presentation.session_transport.data_channel.enable", true]]},
|
||||||
|
runTests);
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -156,7 +156,6 @@ function runTests() {
|
||||||
then(teardown);
|
then(teardown);
|
||||||
}
|
}
|
||||||
|
|
||||||
//SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: true, context: document},
|
{type: 'presentation-device-manage', allow: true, context: document},
|
||||||
|
|
|
@ -116,15 +116,13 @@ function runTests() {
|
||||||
then(testIncomingSessionRequest);
|
then(testIncomingSessionRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
{type: 'presentation', allow: true, context: document},
|
{type: 'presentation', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false]]},
|
||||||
["dom.presentation.test.stage", 0]]},
|
|
||||||
runTests);
|
runTests);
|
||||||
});
|
});
|
||||||
|
|
|
@ -91,15 +91,13 @@ function runTests() {
|
||||||
then(testIncomingSessionRequest);
|
then(testIncomingSessionRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
{type: 'presentation', allow: true, context: document},
|
{type: 'presentation', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false]]},
|
||||||
["dom.presentation.test.stage", 0]]},
|
|
||||||
runTests);
|
runTests);
|
||||||
});
|
});
|
||||||
|
|
|
@ -65,15 +65,13 @@ function runTests() {
|
||||||
then(teardown);
|
then(teardown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
{type: 'presentation', allow: true, context: document},
|
{type: 'presentation', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false],
|
||||||
["dom.presentation.test.stage", 0],
|
|
||||||
["presentation.receiver.loading.timeout", 10]]},
|
["presentation.receiver.loading.timeout", 10]]},
|
||||||
runTests);
|
runTests);
|
||||||
});
|
});
|
|
@ -157,7 +157,6 @@ function runTests() {
|
||||||
then(testIncomingSessionRequest);
|
then(testIncomingSessionRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
|
@ -165,8 +164,7 @@ SpecialPowers.pushPermissions([
|
||||||
{type: 'browser', allow: true, context: document},
|
{type: 'browser', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false],
|
||||||
["dom.presentation.test.stage", 0],
|
|
||||||
["dom.mozBrowserFramesEnabled", true],
|
["dom.mozBrowserFramesEnabled", true],
|
||||||
["dom.ipc.browser_frames.oop_by_default", true]]},
|
["dom.ipc.browser_frames.oop_by_default", true]]},
|
||||||
runTests);
|
runTests);
|
|
@ -186,15 +186,13 @@ function runTests() {
|
||||||
then(teardown);
|
then(teardown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
{type: 'presentation', allow: true, context: document},
|
{type: 'presentation', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false]]},
|
||||||
["dom.presentation.test.stage", 0]]},
|
|
||||||
runTests);
|
runTests);
|
||||||
});
|
});
|
||||||
|
|
|
@ -134,15 +134,13 @@ function runTests() {
|
||||||
then(teardown);
|
then(teardown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
{type: 'presentation', allow: true, context: document},
|
{type: 'presentation', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false]]},
|
||||||
["dom.presentation.test.stage", 0]]},
|
|
||||||
runTests);
|
runTests);
|
||||||
});
|
});
|
||||||
|
|
|
@ -140,15 +140,13 @@ function runTests() {
|
||||||
then(teardown);
|
then(teardown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
{type: 'presentation', allow: true, context: document},
|
{type: 'presentation', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false]]},
|
||||||
["dom.presentation.test.stage", 0]]},
|
|
||||||
runTests);
|
runTests);
|
||||||
});
|
});
|
||||||
|
|
|
@ -344,15 +344,13 @@ function runTests() {
|
||||||
then(teardown);
|
then(teardown);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.expectAssertions(0, 5);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
SpecialPowers.pushPermissions([
|
SpecialPowers.pushPermissions([
|
||||||
{type: 'presentation-device-manage', allow: false, context: document},
|
{type: 'presentation-device-manage', allow: false, context: document},
|
||||||
{type: 'presentation', allow: true, context: document},
|
{type: 'presentation', allow: true, context: document},
|
||||||
], function() {
|
], function() {
|
||||||
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
|
||||||
["dom.presentation.test.enabled", true],
|
["dom.presentation.session_transport.data_channel.enable", false]]},
|
||||||
["dom.presentation.test.stage", 0]]},
|
|
||||||
runTests);
|
runTests);
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,7 +43,7 @@ interface PresentationConnection : EventTarget {
|
||||||
*
|
*
|
||||||
* This function only works when the state is "connected".
|
* This function only works when the state is "connected".
|
||||||
*
|
*
|
||||||
* TODO bug 1148307 Implement PresentationSessionTransport with DataChannel to
|
* TODO bug 1228474 Implement PresentationSessionTransport with DataChannel to
|
||||||
* support other binary types.
|
* support other binary types.
|
||||||
*/
|
*/
|
||||||
[Throws]
|
[Throws]
|
||||||
|
|
|
@ -5064,6 +5064,7 @@ pref("dom.presentation.tcp_server.debug", false);
|
||||||
pref("dom.presentation.discovery.enabled", false);
|
pref("dom.presentation.discovery.enabled", false);
|
||||||
pref("dom.presentation.discovery.timeout_ms", 10000);
|
pref("dom.presentation.discovery.timeout_ms", 10000);
|
||||||
pref("dom.presentation.discoverable", false);
|
pref("dom.presentation.discoverable", false);
|
||||||
|
pref("dom.presentation.session_transport.data_channel.enable", true);
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
#if !defined(RELEASE_BUILD) || defined(DEBUG)
|
#if !defined(RELEASE_BUILD) || defined(DEBUG)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче