--- a/dom/presentation/PresentationSessionInfo.cpp
+++ b/dom/presentation/PresentationSessionInfo.cpp
@@ -643,32 +643,25 @@ PresentationControllingInfo::GetAddress(
RefPtr<PresentationNetworkHelper> networkHelper =
new PresentationNetworkHelper(this,
&PresentationControllingInfo::OnGetAddress);
nsresult rv = networkHelper->GetWifiIPAddress();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
-#elif defined(MOZ_MULET)
- // In simulator,we need to use the "127.0.0.1" as target address.
- NS_DispatchToMainThread(
- NewRunnableMethod<nsCString>(
- this,
- &PresentationControllingInfo::OnGetAddress,
- "127.0.0.1"));
+#else
+ nsCOMPtr<nsINetworkInfoService> networkInfo = do_GetService(NETWORKINFOSERVICE_CONTRACT_ID);
+ MOZ_ASSERT(networkInfo);
-#else
- // TODO Get host IP via other platforms.
+ nsresult rv = networkInfo->ListNetworkAddresses(this);
- NS_DispatchToMainThread(
- NewRunnableMethod<nsCString>(
- this,
- &PresentationControllingInfo::OnGetAddress,
- EmptyCString()));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
#endif
return NS_OK;
}
nsresult
PresentationControllingInfo::OnGetAddress(const nsACString& aAddress)
{
@@ -947,16 +940,60 @@ PresentationControllingInfo::Reconnect(n
rv = mControlChannel->Reconnect(mSessionId, GetUrl());
if (NS_WARN_IF(NS_FAILED(rv))) {
return mReconnectCallback->NotifyError(rv);
}
return NS_OK;
}
+// nsIListNetworkAddressesListener
+NS_IMETHODIMP
+PresentationControllingInfo::OnListedNetworkAddresses(const char** aAddressArray,
+ uint32_t aAddressArraySize)
+{
+ if (!aAddressArraySize) {
+ return OnListNetworkAddressesFailed();
+ }
+
+ // TODO bug 1228504 Take all IP addresses in PresentationChannelDescription
+ // into account. And at the first stage Presentation API is only exposed on
+ // Firefox OS where the first IP appears enough for most scenarios.
+
+ nsAutoCString ip;
+ ip.Assign(aAddressArray[0]);
+
+ // On Firefox desktop, the IP address is retrieved from a callback function.
+ // To make consistent code sequence, following function call is dispatched
+ // into main thread instead of calling it directly.
+ NS_DispatchToMainThread(
+ NewRunnableMethod<nsCString>(
+ this,
+ &PresentationControllingInfo::OnGetAddress,
+ ip));
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PresentationControllingInfo::OnListNetworkAddressesFailed()
+{
+ PRES_ERROR("PresentationControllingInfo:OnListNetworkAddressesFailed");
+
+ // In 1-UA case, transport channel can still be established
+ // on loopback interface even if no network address available.
+ NS_DispatchToMainThread(
+ NewRunnableMethod<nsCString>(
+ this,
+ &PresentationControllingInfo::OnGetAddress,
+ "127.0.0.1"));
+
+ return NS_OK;
+}
+
/**
* 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.
--- a/dom/presentation/PresentationSessionInfo.h
+++ b/dom/presentation/PresentationSessionInfo.h
@@ -8,16 +8,17 @@
#define mozilla_dom_PresentationSessionInfo_h
#include "base/process.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/RefPtr.h"
#include "nsCOMPtr.h"
+#include "nsINetworkInfoService.h"
#include "nsIPresentationControlChannel.h"
#include "nsIPresentationDevice.h"
#include "nsIPresentationListener.h"
#include "nsIPresentationService.h"
#include "nsIPresentationSessionTransport.h"
#include "nsIPresentationSessionTransportBuilder.h"
#include "nsIServerSocket.h"
#include "nsITimer.h"
@@ -166,21 +167,23 @@ protected:
nsCOMPtr<nsIPresentationSessionTransport> mTransport;
nsCOMPtr<nsIPresentationControlChannel> mControlChannel;
nsCOMPtr<nsIPresentationSessionTransportBuilder> mBuilder;
};
// Session info with controlling browsing context (sender side) behaviors.
class PresentationControllingInfo final : public PresentationSessionInfo
, public nsIServerSocketListener
+ , public nsIListNetworkAddressesListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIPRESENTATIONCONTROLCHANNELLISTENER
NS_DECL_NSISERVERSOCKETLISTENER
+ NS_DECL_NSILISTNETWORKADDRESSESLISTENER
PresentationControllingInfo(const nsAString& aUrl,
const nsAString& aSessionId)
: PresentationSessionInfo(aUrl,
aSessionId,
nsIPresentationService::ROLE_CONTROLLER)
{}
--- a/dom/presentation/PresentationTCPSessionTransport.cpp
+++ b/dom/presentation/PresentationTCPSessionTransport.cpp
@@ -323,16 +323,22 @@ PresentationTCPSessionTransport::GetCall
callback.forget(aCallback);
return NS_OK;
}
NS_IMETHODIMP
PresentationTCPSessionTransport::SetCallback(nsIPresentationSessionTransportCallback* aCallback)
{
mCallback = aCallback;
+
+ if (!!mCallback && ReadyState::OPEN == mReadyState) {
+ // Notify the transport channel is ready.
+ NS_WARN_IF(NS_FAILED(mCallback->NotifyTransportReady()));
+ }
+
return NS_OK;
}
NS_IMETHODIMP
PresentationTCPSessionTransport::GetSelfAddress(nsINetAddr** aSelfAddress)
{
if (NS_WARN_IF(!mTransport)) {
return NS_ERROR_DOM_INVALID_STATE_ERR;
--- a/dom/presentation/tests/mochitest/PresentationSessionChromeScript.js
+++ b/dom/presentation/tests/mochitest/PresentationSessionChromeScript.js
@@ -369,17 +369,17 @@ function tearDown() {
mockedDevicePrompt.request = null;
mockedSessionTransport.callback = null;
var deviceManager = Cc['@mozilla.org/presentation-device/manager;1']
.getService(Ci.nsIPresentationDeviceManager);
deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener).removeDevice(mockedDevice);
// Register original factories.
- for (var data in originalFactoryData) {
+ for (var data of originalFactoryData) {
registerOriginalFactory(data.contractId, data.mockedClassId,
data.mockedFactory, data.originalClassId,
data.originalFactory);
}
sendAsyncMessage('teardown-complete');
}
--- a/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
+++ b/dom/presentation/tests/mochitest/PresentationSessionChromeScript1UA.js
@@ -3,163 +3,29 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components;
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+Cu.import('resource://gre/modules/Services.jsm');
const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
function debug(str) {
// dump('DEBUG -*- PresentationSessionChromeScript1UA -*-: ' + str + '\n');
}
const originalFactoryData = [];
var sessionId; // Store the uuid generated by PresentationRequest.
-const address = Cc["@mozilla.org/supports-cstring;1"]
- .createInstance(Ci.nsISupportsCString);
-address.data = "127.0.0.1";
-const addresses = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
-addresses.appendElement(address, false);
var triggerControlChannelError = false; // For simulating error during control channel establishment.
-function mockChannelDescription(role) {
- this.QueryInterface = XPCOMUtils.generateQI([Ci.nsIPresentationChannelDescription]);
- this.role = role;
- this.type = Ci.nsIPresentationChannelDescription.TYPE_TCP;
- this.tcpAddress = addresses;
- this.tcpPort = (role === 'sender' ? 1234 : 4321); // either sender or receiver
-}
-
-const mockChannelDescriptionOfSender = new mockChannelDescription('sender');
-const mockChannelDescriptionOfReceiver = new mockChannelDescription('receiver');
-
-const mockServerSocket = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIServerSocket,
- Ci.nsIFactory]),
- createInstance: function(aOuter, aIID) {
- if (aOuter) {
- throw Components.results.NS_ERROR_NO_AGGREGATION;
- }
- return this.QueryInterface(aIID);
- },
- get port() {
- return this._port;
- },
- set listener(listener) {
- this._listener = listener;
- },
- init: function(port, loopbackOnly, backLog) {
- this._port = (port == -1 ? 5678 : port);
- },
- asyncListen: function(listener) {
- this._listener = listener;
- },
- close: function() {
- this._listener.onStopListening(this, Cr.NS_BINDING_ABORTED);
- },
- onSocketAccepted: function(serverSocket, socketTransport) {
- this._listener.onSocketAccepted(serverSocket, socketTransport);
- }
-};
-
-// mockSessionTransport
-var mockSessionTransportOfSender = undefined;
-var mockSessionTransportOfReceiver = undefined;
-
-function mockSessionTransport() {}
-
-mockSessionTransport.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationSessionTransport,
- Ci.nsIPresentationTCPSessionTransportBuilder]),
- set callback(callback) {
- this._callback = callback;
- },
- get callback() {
- return this._callback;
- },
- get selfAddress() {
- return this._selfAddress;
- },
- buildTCPSenderTransport: function(transport, listener) {
- mockSessionTransportOfSender = this;
- this._listener = listener;
- this._role = Ci.nsIPresentationService.ROLE_CONTROLLER;
-
- this._listener.onSessionTransport(this);
- this._listener = null;
- this.simulateTransportReady();
- },
- buildTCPReceiverTransport: function(description, listener) {
- mockSessionTransportOfReceiver = this;
- this._listener = listener;
- this._role = Ci.nsIPresentationService.ROLE_RECEIVER;
-
- var addresses = description.QueryInterface(Ci.nsIPresentationChannelDescription)
- .tcpAddress;
- this._selfAddress = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsINetAddr]),
- address: (addresses.length > 0) ?
- addresses.queryElementAt(0, Ci.nsISupportsCString).data : '',
- port: description.QueryInterface(Ci.nsIPresentationChannelDescription)
- .tcpPort,
- };
-
- this._listener.onSessionTransport(this);
- this._listener = null;
- },
- enableDataNotification: function() {
- },
- send: function(data) {
- debug('Send message: ' + data);
- if (this._role === Ci.nsIPresentationService.ROLE_CONTROLLER) {
- mockSessionTransportOfReceiver._callback.notifyData(data);
- }
- if (this._role === Ci.nsIPresentationService.ROLE_RECEIVER) {
- mockSessionTransportOfSender._callback.notifyData(data);
- }
- },
- close: function(reason) {
- sendAsyncMessage('data-transport-closed', reason);
- this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportClosed(reason);
- if (this._role === Ci.nsIPresentationService.ROLE_CONTROLLER) {
- if (mockSessionTransportOfReceiver._callback) {
- mockSessionTransportOfReceiver._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportClosed(reason);
- }
- }
- else if (this._role === Ci.nsIPresentationService.ROLE_RECEIVER) {
- if (mockSessionTransportOfSender._callback) {
- mockSessionTransportOfSender._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportClosed(reason);
- }
- }
- },
- simulateTransportReady: function() {
- this._callback.QueryInterface(Ci.nsIPresentationSessionTransportCallback).notifyTransportReady();
- },
-};
-
-const mockSessionTransportFactory = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
- createInstance: function(aOuter, aIID) {
- if (aOuter) {
- throw Components.results.NS_ERROR_NO_AGGREGATION;
- }
- var result = new mockSessionTransport();
- return result.QueryInterface(aIID);
- }
-}
-
-const mockSocketTransport = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISocketTransport]),
-};
-
// control channel of sender
const mockControlChannelOfSender = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannel]),
set listener(listener) {
// PresentationControllingInfo::SetControlChannel
if (listener) {
debug('set listener for mockControlChannelOfSender without null');
} else {
@@ -178,17 +44,19 @@ const mockControlChannelOfSender = {
},
notifyReconnected: function() {
// send offer after notifyOpened immediately
this._listener
.QueryInterface(Ci.nsIPresentationControlChannelListener)
.notifyReconnected();
},
sendOffer: function(offer) {
- sendAsyncMessage('offer-sent');
+ Services.tm.mainThread.dispatch(() => {
+ mockControlChannelOfReceiver.onOffer(offer);
+ }, Ci.nsIThread.DISPATCH_NORMAL);
},
onAnswer: function(answer) {
this._listener
.QueryInterface(Ci.nsIPresentationControlChannelListener)
.onAnswer(answer);
},
launch: function(presentationId, url) {
sessionId = presentationId;
@@ -242,20 +110,19 @@ const mockControlChannelOfReceiver = {
.notifyConnected();
},
onOffer: function(offer) {
this._listener
.QueryInterface(Ci.nsIPresentationControlChannelListener)
.onOffer(offer);
},
sendAnswer: function(answer) {
- this._listener
- .QueryInterface(Ci.nsIPresentationSessionTransportCallback)
- .notifyTransportReady();
- sendAsyncMessage('answer-sent');
+ Services.tm.mainThread.dispatch(() => {
+ mockControlChannelOfSender.onAnswer(answer);
+ }, Ci.nsIThread.DISPATCH_NORMAL);
},
disconnect: function(reason) {
if (!this._listener) {
return;
}
this._listener
.QueryInterface(Ci.nsIPresentationControlChannelListener)
@@ -354,22 +221,16 @@ function initMockAndListener() {
originalFactory: originalFactory };
}
// Register mock factories.
const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"]
.getService(Ci.nsIUUIDGenerator);
originalFactoryData.push(registerMockFactory("@mozilla.org/presentation-device/prompt;1",
uuidGenerator.generateUUID(),
mockDevicePrompt));
- originalFactoryData.push(registerMockFactory("@mozilla.org/network/server-socket;1",
- uuidGenerator.generateUUID(),
- mockServerSocket));
- originalFactoryData.push(registerMockFactory("@mozilla.org/presentation/presentationtcpsessiontransport;1",
- uuidGenerator.generateUUID(),
- mockSessionTransportFactory));
originalFactoryData.push(registerMockFactory("@mozilla.org/presentation/requestuiglue;1",
uuidGenerator.generateUUID(),
mockRequestUIGlue));
addMessageListener('trigger-device-add', function() {
debug('Got message: trigger-device-add');
var deviceManager = Cc['@mozilla.org/presentation-device/manager;1']
.getService(Ci.nsIPresentationDeviceManager);
@@ -422,27 +283,16 @@ function initMockAndListener() {
.getService(Ci.nsIPresentationDeviceManager);
deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener)
.onReconnectRequest(mockDevice,
url,
sessionId,
mockControlChannelOfReceiver);
});
- addMessageListener('trigger-on-offer', function() {
- debug('Got message: trigger-on-offer');
- mockControlChannelOfReceiver.onOffer(mockChannelDescriptionOfSender);
- mockServerSocket.onSocketAccepted(mockServerSocket, mockSocketTransport);
- });
-
- addMessageListener('trigger-on-answer', function() {
- debug('Got message: trigger-on-answer');
- mockControlChannelOfSender.onAnswer(mockChannelDescriptionOfReceiver);
- });
-
// Used to call sendAsyncMessage in chrome script from receiver.
addMessageListener('forward-command', function(command_data) {
let command = JSON.parse(command_data);
sendAsyncMessage(command.name, command.data);
});
addMessageListener('teardown', teardown);
@@ -454,35 +304,33 @@ function initMockAndListener() {
sendAsyncMessage('promise-setup-ready');
}, 'setup-request-promise', false);
}
function teardown() {
function registerOriginalFactory(contractId, mockedClassId, mockedFactory, originalClassId, originalFactory) {
if (originalFactory) {
+ var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
registrar.unregisterFactory(mockedClassId, mockedFactory);
registrar.registerFactory(originalClassId, "", contractId, originalFactory);
}
}
mockRequestUIGlue.promise = null;
- mockServerSocket.listener = null;
- mockSessionTransportOfSender.callback = null;
- mockSessionTransportOfReceiver.callback = null;
mockControlChannelOfSender.listener = null;
mockControlChannelOfReceiver.listener = null;
mockDevicePrompt.request = null;
var deviceManager = Cc['@mozilla.org/presentation-device/manager;1']
.getService(Ci.nsIPresentationDeviceManager);
deviceManager.QueryInterface(Ci.nsIPresentationDeviceListener)
.removeDevice(mockDevice);
// Register original factories.
- for (var data in originalFactoryData) {
+ for (var data of originalFactoryData) {
registerOriginalFactory(data.contractId, data.mockClassId,
data.mockFactory, data.originalClassId,
data.originalFactory);
}
sendAsyncMessage('teardown-complete');
}
initMockAndListener();
--- a/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js
+++ b/dom/presentation/tests/mochitest/PresentationSessionFrameScript.js
@@ -152,17 +152,17 @@ function loadPrivilegedScriptTest() {
}
};
function tearDown() {
mockedSessionTransport.callback = null;
/* Register original factories. */
- for (var data in originalFactoryData) {
+ for (var data of originalFactoryData) {
registerOriginalFactory(data.contractId, data.mockedClassId,
data.mockedFactory, data.originalClassId,
data.originalFactory);
}
sendMessage("teardown-complete");
}
--- a/dom/presentation/tests/mochitest/mochitest.ini
+++ b/dom/presentation/tests/mochitest/mochitest.ini
@@ -1,15 +1,16 @@
[DEFAULT]
support-files =
PresentationDeviceInfoChromeScript.js
PresentationSessionChromeScript.js
PresentationSessionFrameScript.js
PresentationSessionChromeScript1UA.js
file_presentation_1ua_receiver.html
+ test_presentation_1ua_sender_and_receiver.js
file_presentation_non_receiver_inner_iframe.html
file_presentation_non_receiver.html
file_presentation_receiver.html
file_presentation_receiver_establish_connection_error.html
file_presentation_receiver_inner_iframe.html
file_presentation_1ua_wentaway.html
test_presentation_1ua_connection_wentaway.js
file_presentation_receiver_auxiliary_navigation.html
@@ -24,17 +25,17 @@ support-files =
file_presentation_unknown_content_type.test^headers^
test_presentation_tcp_receiver_establish_connection_unknown_content_type.js
[test_presentation_dc_sender.html]
[test_presentation_dc_receiver.html]
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
[test_presentation_dc_receiver_oop.html]
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
-[test_presentation_1ua_sender_and_receiver.html]
+[test_presentation_1ua_sender_and_receiver_inproc.html]
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
[test_presentation_1ua_sender_and_receiver_oop.html]
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
[test_presentation_1ua_connection_wentaway_inproc.html]
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
[test_presentation_1ua_connection_wentaway_oop.html]
skip-if = (e10s || toolkit == 'gonk' || toolkit == 'android') # Bug 1129785
[test_presentation_device_info_permission.html]
--- a/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway.js
+++ b/dom/presentation/tests/mochitest/test_presentation_1ua_connection_wentaway.js
@@ -79,28 +79,16 @@ function setup() {
gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
debug('Got message: promise-setup-ready');
gScript.removeMessageListener('promise-setup-ready',
promiseSetupReadyHandler);
gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
});
- gScript.addMessageListener('offer-sent', function offerSentHandler() {
- debug('Got message: offer-sent');
- gScript.removeMessageListener('offer-sent', offerSentHandler);
- gScript.sendAsyncMessage('trigger-on-offer');
- });
-
- gScript.addMessageListener('answer-sent', function answerSentHandler() {
- debug('Got message: answer-sent');
- gScript.removeMessageListener('answer-sent', answerSentHandler);
- gScript.sendAsyncMessage('trigger-on-answer');
- });
-
return Promise.resolve();
}
function testCreateRequest() {
return new Promise(function(aResolve, aReject) {
info('Sender: --- testCreateRequest ---');
request = new PresentationRequest(receiverUrl);
request.getAvailability().then((aAvailability) => {
deleted file mode 100644
--- a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.html
+++ /dev/null
@@ -1,329 +0,0 @@
-<!DOCTYPE HTML>
-<!-- vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: -->
-<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 when sender and receiver at the same 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=1234492">
- Test for B2G Presentation API when sender and receiver at the same side</a>
- <script type="application/javascript;version=1.8">
-
-'use strict';
-
-function debug(str) {
- // info(str);
-}
-
-var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js'));
-var receiverUrl = SimpleTest.getTestFileURL('file_presentation_1ua_receiver.html');
-var request;
-var connection;
-var receiverIframe;
-var presentationId;
-
-function postMessageToIframe(aType) {
- receiverIframe.src = receiverUrl + "#" +
- encodeURIComponent(JSON.stringify({ type: aType }));
-}
-
-function setup() {
-
- gScript.addMessageListener('device-prompt', function devicePromptHandler() {
- debug('Got message: device-prompt');
- gScript.removeMessageListener('device-prompt', devicePromptHandler);
- gScript.sendAsyncMessage('trigger-device-prompt-select');
- });
-
- gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
- gScript.removeMessageListener('control-channel-established',
- controlChannelEstablishedHandler);
- gScript.sendAsyncMessage("trigger-control-channel-open");
- });
-
- gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) {
- debug('Got message: sender-launch');
- gScript.removeMessageListener('sender-launch', senderLaunchHandler);
- is(url, receiverUrl, 'Receiver: should receive the same url');
- receiverIframe = document.createElement('iframe');
- receiverIframe.setAttribute('src', receiverUrl);
- receiverIframe.setAttribute("mozbrowser", "true");
- receiverIframe.setAttribute("mozpresentation", receiverUrl);
-
- // This event is triggered when the iframe calls "alert".
- receiverIframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) {
- var message = evt.detail.message;
- debug('Got iframe message: ' + message);
- if (/^OK /.exec(message)) {
- ok(true, message.replace(/^OK /, ""));
- } else if (/^KO /.exec(message)) {
- ok(false, message.replace(/^KO /, ""));
- } else if (/^INFO /.exec(message)) {
- info(message.replace(/^INFO /, ""));
- } else if (/^COMMAND /.exec(message)) {
- var command = JSON.parse(message.replace(/^COMMAND /, ""));
- gScript.sendAsyncMessage(command.name, command.data);
- } else if (/^DONE$/.exec(message)) {
- receiverIframe.removeEventListener("mozbrowsershowmodalprompt",
- receiverListener);
- }
- }, false);
-
- var promise = new Promise(function(aResolve, aReject) {
- document.body.appendChild(receiverIframe);
- aResolve(receiverIframe);
- });
-
- var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
- .getService(SpecialPowers.Ci.nsIObserverService);
- obs.notifyObservers(promise, 'setup-request-promise', null);
- });
-
- gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
- debug('Got message: promise-setup-ready');
- gScript.removeMessageListener('promise-setup-ready', promiseSetupReadyHandler);
- gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
- });
-
- gScript.addMessageListener('offer-sent', function offerSentHandler() {
- debug('Got message: offer-sent');
- gScript.removeMessageListener('offer-sent', offerSentHandler);
- gScript.sendAsyncMessage('trigger-on-offer');
- });
-
- gScript.addMessageListener('answer-sent', function answerSentHandler() {
- debug('Got message: answer-sent');
- gScript.removeMessageListener('answer-sent', answerSentHandler);
- gScript.sendAsyncMessage('trigger-on-answer');
- });
-
- return Promise.resolve();
-}
-
-function testCreateRequest() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testCreateRequest ---');
- request = new PresentationRequest("file_presentation_1ua_receiver.html");
- request.getAvailability().then((aAvailability) => {
- aAvailability.onchange = function() {
- aAvailability.onchange = null;
- ok(aAvailability.value, "Sender: Device should be available.");
- aResolve();
- }
- }).catch((aError) => {
- ok(false, "Sender: Error occurred when getting availability: " + aError);
- teardown();
- aReject();
- });
-
- gScript.sendAsyncMessage('trigger-device-add');
- });
-}
-
-function testStartConnection() {
- return new Promise(function(aResolve, aReject) {
- request.start().then((aConnection) => {
- connection = aConnection;
- ok(connection, "Sender: Connection should be available.");
- ok(connection.id, "Sender: Connection ID should be set.");
- is(connection.state, "connecting", "The initial state should be connecting.");
- is(connection.url, receiverUrl, "request URL should be expanded to absolute URL");
- connection.onconnect = function() {
- connection.onconnect = null;
- is(connection.state, "connected", "Connection should be connected.");
- presentationId = connection.id;
- aResolve();
- };
- }).catch((aError) => {
- ok(false, "Sender: Error occurred when establishing a connection: " + aError);
- teardown();
- aReject();
- });
- });
-}
-
-function testSendMessage() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testSendMessage ---');
- gScript.addMessageListener('trigger-message-from-sender', function triggerMessageFromSenderHandler() {
- debug('Got message: trigger-message-from-sender');
- gScript.removeMessageListener('trigger-message-from-sender', triggerMessageFromSenderHandler);
- info('Send message to receiver');
- connection.send('msg-sender-to-receiver');
- });
-
- gScript.addMessageListener('message-from-sender-received', function messageFromSenderReceivedHandler() {
- debug('Got message: message-from-sender-received');
- gScript.removeMessageListener('message-from-sender-received', messageFromSenderReceivedHandler);
- aResolve();
- });
- });
-}
-
-function testIncomingMessage() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testIncomingMessage ---');
- connection.addEventListener('message', function messageHandler(evt) {
- connection.removeEventListener('message', messageHandler);
- let msg = evt.data;
- is(msg, "msg-receiver-to-sender", "Sender: Sender should receive message from Receiver");
- postMessageToIframe('message-from-receiver-received');
- aResolve();
- });
- postMessageToIframe('trigger-message-from-receiver');
- });
-}
-
-function testCloseConnection() {
- info('Sender: --- testCloseConnection ---');
- // Test terminate immediate after close.
- function controlChannelEstablishedHandler()
- {
- gScript.removeMessageListener('control-channel-established',
- controlChannelEstablishedHandler);
- ok(false, "terminate after close should do nothing");
- }
- gScript.addMessageListener('ready-to-close', function onReadyToClose() {
- gScript.removeMessageListener('ready-to-close', onReadyToClose);
- connection.close();
-
- gScript.addMessageListener('control-channel-established', controlChannelEstablishedHandler);
- connection.terminate();
- });
-
- return Promise.all([
- new Promise(function(aResolve, aReject) {
- connection.onclose = function() {
- connection.onclose = null;
- is(connection.state, 'closed', 'Sender: Connection should be closed.');
- gScript.removeMessageListener('control-channel-established',
- controlChannelEstablishedHandler);
- aResolve();
- };
- }),
- new Promise(function(aResolve, aReject) {
- gScript.addMessageListener('receiver-closed', function onReceiverClosed() {
- gScript.removeMessageListener('receiver-closed', onReceiverClosed);
- gScript.removeMessageListener('control-channel-established',
- controlChannelEstablishedHandler);
- aResolve();
- });
- }),
- ]);
-}
-
-function testTerminateAfterClose() {
- info('Sender: --- testTerminateAfterClose ---');
- return Promise.race([
- new Promise(function(aResolve, aReject) {
- connection.onterminate = function() {
- connection.onterminate = null;
- ok(false, 'terminate after close should do nothing');
- aResolve();
- };
- connection.terminate();
- }),
- new Promise(function(aResolve, aReject) {
- setTimeout(function() {
- is(connection.state, 'closed', 'Sender: Connection should be closed.');
- aResolve();
- }, 3000);
- }),
- ]);
-}
-
-function testReconnect() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testReconnect ---');
- gScript.addMessageListener('control-channel-established', function controlChannelEstablished() {
- gScript.removeMessageListener('control-channel-established', controlChannelEstablished);
- gScript.sendAsyncMessage("trigger-control-channel-open");
- });
-
- gScript.addMessageListener('start-reconnect', function startReconnectHandler(url) {
- debug('Got message: start-reconnect');
- gScript.removeMessageListener('start-reconnect', startReconnectHandler);
- is(url, receiverUrl, "URLs should be the same.")
- gScript.sendAsyncMessage('trigger-reconnected-acked', url);
- });
-
- gScript.addMessageListener('offer-sent', function offerSentHandler() {
- debug('Got message: offer-sent');
- gScript.removeMessageListener('offer-sent', offerSentHandler);
- gScript.sendAsyncMessage('trigger-on-offer');
- });
-
- gScript.addMessageListener('answer-sent', function answerSentHandler() {
- debug('Got message: answer-sent');
- gScript.removeMessageListener('answer-sent', answerSentHandler);
- gScript.sendAsyncMessage('trigger-on-answer');
- });
-
- gScript.addMessageListener('ready-to-reconnect', function onReadyToReconnect() {
- gScript.removeMessageListener('ready-to-reconnect', onReadyToReconnect);
- request.reconnect(presentationId).then((aConnection) => {
- connection = aConnection;
- ok(connection, "Sender: Connection should be available.");
- is(connection.id, presentationId, "The presentationId should be the same.");
- is(connection.state, "connecting", "The initial state should be connecting.");
- connection.onconnect = function() {
- connection.onconnect = null;
- is(connection.state, "connected", "Connection should be connected.");
- aResolve();
- };
- }).catch((aError) => {
- ok(false, "Sender: Error occurred when establishing a connection: " + aError);
- teardown();
- aReject();
- });
- });
- });
-}
-
-function teardown() {
- gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
- debug('Got message: teardown-complete');
- gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
- gScript.destroy();
- SimpleTest.finish();
- });
-
- gScript.sendAsyncMessage('teardown');
-}
-
-function runTests() {
- setup().then(testCreateRequest)
- .then(testStartConnection)
- .then(testSendMessage)
- .then(testIncomingMessage)
- .then(testCloseConnection)
- .then(testReconnect)
- .then(testCloseConnection)
- .then(testTerminateAfterClose)
- .then(teardown);
-}
-
-SimpleTest.waitForExplicitFinish();
-SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event');
-SpecialPowers.pushPermissions([
- {type: 'presentation-device-manage', allow: false, context: document},
- {type: 'presentation', allow: true, context: document},
- {type: "browser", allow: true, context: document},
-], () => {
- SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
- /* Mocked TCP session transport builder in the test */
- ["dom.presentation.session_transport.data_channel.enable", false],
- ["dom.presentation.test.enabled", true],
- ["dom.presentation.test.stage", 0],
- ["dom.mozBrowserFramesEnabled", true]]},
- runTests);
-});
-
- </script>
- </body>
-</html>
new file mode 100644
--- /dev/null
+++ b/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver.js
@@ -0,0 +1,292 @@
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+* You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict';
+
+function debug(str) {
+ // info(str);
+}
+
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js'));
+var receiverUrl = SimpleTest.getTestFileURL('file_presentation_1ua_receiver.html');
+var request;
+var connection;
+var receiverIframe;
+var presentationId;
+
+function postMessageToIframe(aType) {
+ receiverIframe.src = receiverUrl + "#" +
+ encodeURIComponent(JSON.stringify({ type: aType }));
+}
+
+function setup() {
+
+ gScript.addMessageListener('device-prompt', function devicePromptHandler() {
+ debug('Got message: device-prompt');
+ gScript.removeMessageListener('device-prompt', devicePromptHandler);
+ gScript.sendAsyncMessage('trigger-device-prompt-select');
+ });
+
+ gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
+ gScript.removeMessageListener('control-channel-established',
+ controlChannelEstablishedHandler);
+ gScript.sendAsyncMessage("trigger-control-channel-open");
+ });
+
+ gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) {
+ debug('Got message: sender-launch');
+ gScript.removeMessageListener('sender-launch', senderLaunchHandler);
+ is(url, receiverUrl, 'Receiver: should receive the same url');
+ receiverIframe = document.createElement('iframe');
+ receiverIframe.setAttribute('src', receiverUrl);
+ receiverIframe.setAttribute("mozbrowser", "true");
+ receiverIframe.setAttribute("mozpresentation", receiverUrl);
+ var oop = location.pathname.indexOf('_inproc') == -1;
+ receiverIframe.setAttribute("remote", oop);
+
+ // This event is triggered when the iframe calls "alert".
+ receiverIframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) {
+ var message = evt.detail.message;
+ debug('Got iframe message: ' + message);
+ if (/^OK /.exec(message)) {
+ ok(true, message.replace(/^OK /, ""));
+ } else if (/^KO /.exec(message)) {
+ ok(false, message.replace(/^KO /, ""));
+ } else if (/^INFO /.exec(message)) {
+ info(message.replace(/^INFO /, ""));
+ } else if (/^COMMAND /.exec(message)) {
+ var command = JSON.parse(message.replace(/^COMMAND /, ""));
+ gScript.sendAsyncMessage(command.name, command.data);
+ } else if (/^DONE$/.exec(message)) {
+ receiverIframe.removeEventListener("mozbrowsershowmodalprompt",
+ receiverListener);
+ }
+ }, false);
+
+ var promise = new Promise(function(aResolve, aReject) {
+ document.body.appendChild(receiverIframe);
+ aResolve(receiverIframe);
+ });
+
+ var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
+ .getService(SpecialPowers.Ci.nsIObserverService);
+ obs.notifyObservers(promise, 'setup-request-promise', null);
+ });
+
+ gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
+ debug('Got message: promise-setup-ready');
+ gScript.removeMessageListener('promise-setup-ready', promiseSetupReadyHandler);
+ gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
+ });
+
+ return Promise.resolve();
+}
+
+function testCreateRequest() {
+ return new Promise(function(aResolve, aReject) {
+ info('Sender: --- testCreateRequest ---');
+ request = new PresentationRequest("file_presentation_1ua_receiver.html");
+ request.getAvailability().then((aAvailability) => {
+ aAvailability.onchange = function() {
+ aAvailability.onchange = null;
+ ok(aAvailability.value, "Sender: Device should be available.");
+ aResolve();
+ }
+ }).catch((aError) => {
+ ok(false, "Sender: Error occurred when getting availability: " + aError);
+ teardown();
+ aReject();
+ });
+
+ gScript.sendAsyncMessage('trigger-device-add');
+ });
+}
+
+function testStartConnection() {
+ return new Promise(function(aResolve, aReject) {
+ request.start().then((aConnection) => {
+ connection = aConnection;
+ ok(connection, "Sender: Connection should be available.");
+ ok(connection.id, "Sender: Connection ID should be set.");
+ is(connection.state, "connecting", "The initial state should be connecting.");
+ is(connection.url, receiverUrl, "request URL should be expanded to absolute URL");
+ connection.onconnect = function() {
+ connection.onconnect = null;
+ is(connection.state, "connected", "Connection should be connected.");
+ presentationId = connection.id;
+ aResolve();
+ };
+ }).catch((aError) => {
+ ok(false, "Sender: Error occurred when establishing a connection: " + aError);
+ teardown();
+ aReject();
+ });
+ });
+}
+
+function testSendMessage() {
+ return new Promise(function(aResolve, aReject) {
+ info('Sender: --- testSendMessage ---');
+ gScript.addMessageListener('trigger-message-from-sender', function triggerMessageFromSenderHandler() {
+ debug('Got message: trigger-message-from-sender');
+ gScript.removeMessageListener('trigger-message-from-sender', triggerMessageFromSenderHandler);
+ info('Send message to receiver');
+ connection.send('msg-sender-to-receiver');
+ });
+
+ gScript.addMessageListener('message-from-sender-received', function messageFromSenderReceivedHandler() {
+ debug('Got message: message-from-sender-received');
+ gScript.removeMessageListener('message-from-sender-received', messageFromSenderReceivedHandler);
+ aResolve();
+ });
+ });
+}
+
+function testIncomingMessage() {
+ return new Promise(function(aResolve, aReject) {
+ info('Sender: --- testIncomingMessage ---');
+ connection.addEventListener('message', function messageHandler(evt) {
+ connection.removeEventListener('message', messageHandler);
+ let msg = evt.data;
+ is(msg, "msg-receiver-to-sender", "Sender: Sender should receive message from Receiver");
+ postMessageToIframe('message-from-receiver-received');
+ aResolve();
+ });
+ postMessageToIframe('trigger-message-from-receiver');
+ });
+}
+
+function testCloseConnection() {
+ info('Sender: --- testCloseConnection ---');
+ // Test terminate immediate after close.
+ function controlChannelEstablishedHandler()
+ {
+ gScript.removeMessageListener('control-channel-established',
+ controlChannelEstablishedHandler);
+ ok(false, "terminate after close should do nothing");
+ }
+ gScript.addMessageListener('ready-to-close', function onReadyToClose() {
+ gScript.removeMessageListener('ready-to-close', onReadyToClose);
+ connection.close();
+
+ gScript.addMessageListener('control-channel-established', controlChannelEstablishedHandler);
+ connection.terminate();
+ });
+
+ return Promise.all([
+ new Promise(function(aResolve, aReject) {
+ connection.onclose = function() {
+ connection.onclose = null;
+ is(connection.state, 'closed', 'Sender: Connection should be closed.');
+ gScript.removeMessageListener('control-channel-established',
+ controlChannelEstablishedHandler);
+ aResolve();
+ };
+ }),
+ new Promise(function(aResolve, aReject) {
+ gScript.addMessageListener('receiver-closed', function onReceiverClosed() {
+ gScript.removeMessageListener('receiver-closed', onReceiverClosed);
+ gScript.removeMessageListener('control-channel-established',
+ controlChannelEstablishedHandler);
+ aResolve();
+ });
+ }),
+ ]);
+}
+
+function testTerminateAfterClose() {
+ info('Sender: --- testTerminateAfterClose ---');
+ return Promise.race([
+ new Promise(function(aResolve, aReject) {
+ connection.onterminate = function() {
+ connection.onterminate = null;
+ ok(false, 'terminate after close should do nothing');
+ aResolve();
+ };
+ connection.terminate();
+ }),
+ new Promise(function(aResolve, aReject) {
+ setTimeout(function() {
+ is(connection.state, 'closed', 'Sender: Connection should be closed.');
+ aResolve();
+ }, 3000);
+ }),
+ ]);
+}
+
+function testReconnect() {
+ return new Promise(function(aResolve, aReject) {
+ info('Sender: --- testReconnect ---');
+ gScript.addMessageListener('control-channel-established', function controlChannelEstablished() {
+ gScript.removeMessageListener('control-channel-established', controlChannelEstablished);
+ gScript.sendAsyncMessage("trigger-control-channel-open");
+ });
+
+ gScript.addMessageListener('start-reconnect', function startReconnectHandler(url) {
+ debug('Got message: start-reconnect');
+ gScript.removeMessageListener('start-reconnect', startReconnectHandler);
+ is(url, receiverUrl, "URLs should be the same.")
+ gScript.sendAsyncMessage('trigger-reconnected-acked', url);
+ });
+
+ gScript.addMessageListener('ready-to-reconnect', function onReadyToReconnect() {
+ gScript.removeMessageListener('ready-to-reconnect', onReadyToReconnect);
+ request.reconnect(presentationId).then((aConnection) => {
+ connection = aConnection;
+ ok(connection, "Sender: Connection should be available.");
+ is(connection.id, presentationId, "The presentationId should be the same.");
+ is(connection.state, "connecting", "The initial state should be connecting.");
+ connection.onconnect = function() {
+ connection.onconnect = null;
+ is(connection.state, "connected", "Connection should be connected.");
+ aResolve();
+ };
+ }).catch((aError) => {
+ ok(false, "Sender: Error occurred when establishing a connection: " + aError);
+ teardown();
+ aReject();
+ });
+ });
+ });
+}
+
+function teardown() {
+ gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
+ debug('Got message: teardown-complete');
+ gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
+ gScript.destroy();
+ SimpleTest.finish();
+ });
+
+ gScript.sendAsyncMessage('teardown');
+}
+
+function runTests() {
+ setup().then(testCreateRequest)
+ .then(testStartConnection)
+ .then(testSendMessage)
+ .then(testIncomingMessage)
+ .then(testCloseConnection)
+ .then(testReconnect)
+ .then(testCloseConnection)
+ .then(testTerminateAfterClose)
+ .then(teardown);
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event');
+SpecialPowers.pushPermissions([
+ {type: 'presentation-device-manage', allow: false, context: document},
+ {type: 'presentation', allow: true, context: document},
+ {type: "browser", allow: true, context: document},
+], () => {
+ SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
+ /* Mocked TCP session transport builder in the test */
+ ["dom.presentation.session_transport.data_channel.enable", false],
+ ["dom.presentation.test.enabled", true],
+ ["dom.presentation.test.stage", 0],
+ ["dom.mozBrowserFramesEnabled", true]]},
+ runTests);
+});
new file mode 100644
--- /dev/null
+++ b/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_inproc.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<!-- vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: -->
+<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 when sender and receiver at the same 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=1234492">
+ Test for B2G Presentation API when sender and receiver at the same side</a>
+ <script type="application/javascript;version=1.8" src="test_presentation_1ua_sender_and_receiver.js">
+ </script>
+ </body>
+</html>
--- a/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_oop.html
+++ b/dom/presentation/tests/mochitest/test_presentation_1ua_sender_and_receiver_oop.html
@@ -7,272 +7,12 @@
<meta charset="utf-8">
<title>Test for B2G Presentation API when sender and receiver at the same side (OOP ver.)</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=1234492">
Test for B2G Presentation API when sender and receiver at the same side (OOP ver.)</a>
-<script type="application/javascript;version=1.8">
-
-'use strict';
-
-var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('PresentationSessionChromeScript1UA.js'));
-var receiverUrl = SimpleTest.getTestFileURL('file_presentation_1ua_receiver.html');
-var request;
-var connection;
-var receiverIframe;
-
-function debug(str) {
- // info(str);
-}
-
-function postMessageToIframe(aType) {
- receiverIframe.src = receiverUrl + "#" +
- encodeURIComponent(JSON.stringify({ type: aType }));
-}
-
-function setup() {
-
- gScript.addMessageListener('device-prompt', function devicePromptHandler() {
- debug('Got message: device-prompt');
- gScript.removeMessageListener('device-prompt', devicePromptHandler);
- gScript.sendAsyncMessage('trigger-device-prompt-select');
- });
-
- gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
- gScript.removeMessageListener('control-channel-established',
- controlChannelEstablishedHandler);
- gScript.sendAsyncMessage("trigger-control-channel-open");
- });
-
- gScript.addMessageListener('sender-launch', function senderLaunchHandler(url) {
- debug('Got message: sender-launch');
- gScript.removeMessageListener('sender-launch', senderLaunchHandler);
- is(url, receiverUrl, 'Receiver: should receive the same url');
- receiverIframe = document.createElement('iframe');
- receiverIframe.setAttribute("remote", "true");
- receiverIframe.setAttribute("mozbrowser", "true");
- receiverIframe.setAttribute("mozpresentation", receiverUrl);
- receiverIframe.setAttribute('src', receiverUrl);
- receiverIframe.addEventListener("mozbrowserloadend", function mozbrowserloadendHander() {
- receiverIframe.removeEventListener("mozbrowserloadend", mozbrowserloadendHander);
- info("Receiver loaded.");
- });
-
- // This event is triggered when the iframe calls "alert".
- receiverIframe.addEventListener("mozbrowsershowmodalprompt", function receiverListener(evt) {
- var message = evt.detail.message;
- if (/^OK /.exec(message)) {
- ok(true, message.replace(/^OK /, ""));
- } else if (/^KO /.exec(message)) {
- ok(false, message.replace(/^KO /, ""));
- } else if (/^INFO /.exec(message)) {
- info(message.replace(/^INFO /, ""));
- } else if (/^COMMAND /.exec(message)) {
- var command = JSON.parse(message.replace(/^COMMAND /, ""));
- gScript.sendAsyncMessage(command.name, command.data);
- } else if (/^DONE$/.exec(message)) {
- receiverIframe.removeEventListener("mozbrowsershowmodalprompt",
- receiverListener);
- }
- }, false);
-
- var promise = new Promise(function(aResolve, aReject) {
- document.body.appendChild(receiverIframe);
- aResolve(receiverIframe);
- });
-
- var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
- .getService(SpecialPowers.Ci.nsIObserverService);
- obs.notifyObservers(promise, 'setup-request-promise', null);
- });
-
- gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
- debug('Got message: promise-setup-ready');
- gScript.removeMessageListener('promise-setup-ready',
- promiseSetupReadyHandler);
- gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
- });
-
- gScript.addMessageListener('offer-sent', function offerSentHandler() {
- debug('Got message: offer-sent');
- gScript.removeMessageListener('offer-sent', offerSentHandler);
- gScript.sendAsyncMessage('trigger-on-offer');
- });
-
- gScript.addMessageListener('answer-sent', function answerSentHandler() {
- debug('Got message: answer-sent');
- gScript.removeMessageListener('answer-sent', answerSentHandler);
- gScript.sendAsyncMessage('trigger-on-answer');
- });
-
- return Promise.resolve();
-}
-
-function testCreateRequest() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testCreateRequest ---');
- request = new PresentationRequest(receiverUrl);
- request.getAvailability()
- .then((aAvailability) => {
- aAvailability.onchange = function() {
- aAvailability.onchange = null;
- ok(aAvailability.value, "Sender: Device should be available.");
- aResolve();
- }
- })
- .catch((aError) => {
- ok(false, "Sender: Error occurred when getting availability: " + aError);
- teardown();
- aReject();
- });
-
- gScript.sendAsyncMessage('trigger-device-add');
- });
-}
-
-function testStartConnection() {
- return new Promise(function(aResolve, aReject) {
- request.start()
- .then((aConnection) => {
- connection = aConnection;
- ok(connection, "Sender: Connection should be available.");
- ok(connection.id, "Sender: Connection ID should be set.");
- is(connection.state, "connecting", "The initial state should be connecting.");
- connection.onconnect = function() {
- connection.onconnect = null;
- is(connection.state, "connected", "Connection should be connected.");
- aResolve();
- };
- })
- .catch((aError) => {
- ok(false, "Sender: Error occurred when establishing a connection: " + aError);
- teardown();
- aReject();
- });
- });
-}
-
-function testSendMessage() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testSendMessage ---');
- gScript.addMessageListener('trigger-message-from-sender', function triggerMessageFromSenderHandler() {
- gScript.removeMessageListener('trigger-message-from-sender', triggerMessageFromSenderHandler);
- info('Send message to receiver');
- connection.send('msg-sender-to-receiver');
- });
-
- gScript.addMessageListener('message-from-sender-received', function messageFromSenderReceivedHandler() {
- gScript.removeMessageListener('message-from-sender-received', messageFromSenderReceivedHandler);
- aResolve();
- });
- });
-}
-
-function testIncomingMessage() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testIncomingMessage ---');
- connection.addEventListener('message', function messageHandler(evt) {
- connection.removeEventListener('message', messageHandler);
- let msg = evt.data;
- is(msg, "msg-receiver-to-sender", "Sender: Sender should receive message from Receiver");
- postMessageToIframe('message-from-receiver-received');
- aResolve();
- });
- postMessageToIframe('trigger-message-from-receiver');
- });
-}
-
-function testCloseConnection() {
- info('Sender: --- testCloseConnection ---');
- gScript.addMessageListener('ready-to-close', function onReadyToClose() {
- gScript.removeMessageListener('ready-to-close', onReadyToClose);
- connection.close();
-
- // Test terminate immediate after close.
- gScript.addMessageListener('control-channel-established', function controlChannelEstablishedHandler() {
- gScript.removeMessageListener('control-channel-established',
- controlChannelEstablishedHandler);
- ok(false, 'terminate after close should do nothing');
- });
- connection.terminate();
- });
-
- return Promise.all([
- new Promise(function(aResolve, aReject) {
- connection.onclose = function() {
- connection.onclose = null;
- is(connection.state, 'closed', 'Sender: Connection should be closed.');
- aResolve();
- };
- }),
- new Promise(function(aResolve, aReject) {
- gScript.addMessageListener('receiver-closed', function onReceiverClosed() {
- gScript.removeMessageListener('receiver-closed', onReceiverClosed);
- aResolve();
- });
- }),
- ]);
-}
-
-function testTerminateAfterClose() {
- info('Sender: --- testTerminateAfterClose ---');
- return Promise.race([
- new Promise(function(aResolve, aReject) {
- connection.onterminate = function() {
- connection.onterminate = null;
- ok(false, 'terminate at closed state should do nothing');
- aResolve();
- };
- connection.terminate();
- }),
- new Promise(function(aResolve, aReject) {
- setTimeout(function() {
- is(connection.state, 'closed', 'Sender: Connection should be closed.');
- aResolve();
- }, 3000);
- }),
- ]);
-}
-
-function teardown() {
- gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
- gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
- gScript.destroy();
- SimpleTest.finish();
- });
-
- gScript.sendAsyncMessage('teardown');
-}
-
-function runTests() {
- setup()
- .then(testCreateRequest)
- .then(testStartConnection)
- .then(testSendMessage)
- .then(testIncomingMessage)
- .then(testCloseConnection)
- .then(testTerminateAfterClose)
- .then(teardown);
-}
-
-SimpleTest.waitForExplicitFinish();
-SimpleTest.requestFlakyTimeout('Test for guarantee not firing async event');
-SpecialPowers.pushPermissions([
- {type: 'presentation-device-manage', allow: false, context: document},
- {type: 'presentation', allow: true, context: document},
- {type: "browser", allow: true, context: document},
-], () => {
- SpecialPowers.pushPrefEnv({ 'set': [["dom.presentation.enabled", true],
- /* Mocked TCP session transport builder in the test */
- ["dom.presentation.session_transport.data_channel.enable", false],
- ["dom.presentation.test.enabled", true],
- ["dom.presentation.test.stage", 0],
- ["dom.mozBrowserFramesEnabled", true],
- ["dom.ipc.browser_frames.oop_by_default", true]]},
- runTests);
-});
-
-</script>
+ <script type="application/javascript;version=1.8" src="test_presentation_1ua_sender_and_receiver.js">
+ </script>
</body>
</html>
--- a/dom/presentation/tests/mochitest/test_presentation_terminate.js
+++ b/dom/presentation/tests/mochitest/test_presentation_terminate.js
@@ -73,28 +73,16 @@ function setup() {
gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
debug('Got message: promise-setup-ready');
gScript.removeMessageListener('promise-setup-ready',
promiseSetupReadyHandler);
gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
});
- gScript.addMessageListener('offer-sent', function offerSentHandler() {
- debug('Got message: offer-sent');
- gScript.removeMessageListener('offer-sent', offerSentHandler);
- gScript.sendAsyncMessage('trigger-on-offer');
- });
-
- gScript.addMessageListener('answer-sent', function answerSentHandler() {
- debug('Got message: answer-sent');
- gScript.removeMessageListener('answer-sent', answerSentHandler);
- gScript.sendAsyncMessage('trigger-on-answer');
- });
-
return Promise.resolve();
}
function testCreateRequest() {
return new Promise(function(aResolve, aReject) {
info('Sender: --- testCreateRequest ---');
request = new PresentationRequest(receiverUrl);
request.getAvailability().then((aAvailability) => {
--- a/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error.js
+++ b/dom/presentation/tests/mochitest/test_presentation_terminate_establish_connection_error.js
@@ -78,28 +78,16 @@ function setup() {
gScript.addMessageListener('promise-setup-ready', function promiseSetupReadyHandler() {
debug('Got message: promise-setup-ready');
gScript.removeMessageListener('promise-setup-ready',
promiseSetupReadyHandler);
gScript.sendAsyncMessage('trigger-on-session-request', receiverUrl);
});
- gScript.addMessageListener('offer-sent', function offerSentHandler() {
- debug('Got message: offer-sent');
- gScript.removeMessageListener('offer-sent', offerSentHandler);
- gScript.sendAsyncMessage('trigger-on-offer');
- });
-
- gScript.addMessageListener('answer-sent', function answerSentHandler() {
- debug('Got message: answer-sent');
- gScript.removeMessageListener('answer-sent', answerSentHandler);
- gScript.sendAsyncMessage('trigger-on-answer');
- });
-
return Promise.resolve();
}
function testCreateRequest() {
return new Promise(function(aResolve, aReject) {
info('Sender: --- testCreateRequest ---');
request = new PresentationRequest(receiverUrl);
request.getAvailability().then((aAvailability) => {
@@ -134,33 +122,41 @@ function testStartConnection() {
ok(false, 'Sender: Error occurred when establishing a connection: ' + aError);
teardown();
aReject();
});
});
}
function testConnectionTerminate() {
- return new Promise(function(aResolve, aReject) {
- info('Sender: --- testConnectionTerminate---');
- gScript.addMessageListener('prepare-for-terminate', function prepareForTerminateHandler() {
- debug('Got message: prepare-for-terminate');
- gScript.removeMessageListener('prepare-for-terminate', prepareForTerminateHandler);
+ info('Sender: --- testConnectionTerminate---');
+ let promise = Promise.all([
+ new Promise(function(aResolve, aReject) {
connection.onclose = function() {
connection.onclose = null;
is(connection.state, 'closed', 'Sender: Connection should be closed.');
+ aResolve();
};
- gScript.sendAsyncMessage('trigger-control-channel-error');
+ }),
+ new Promise(function(aResolve, aReject) {
receiverIframe.addEventListener('mozbrowserclose', function() {
ok(true, 'observe receiver page closing');
aResolve();
});
- postMessageToIframe('ready-to-terminate');
- });
+ })
+ ]);
+
+ gScript.addMessageListener('prepare-for-terminate', function prepareForTerminateHandler() {
+ debug('Got message: prepare-for-terminate');
+ gScript.removeMessageListener('prepare-for-terminate', prepareForTerminateHandler);
+ gScript.sendAsyncMessage('trigger-control-channel-error');
+ postMessageToIframe('ready-to-terminate');
});
+
+ return promise;
}
function teardown() {
gScript.addMessageListener('teardown-complete', function teardownCompleteHandler() {
debug('Got message: teardown-complete');
gScript.removeMessageListener('teardown-complete', teardownCompleteHandler);
gScript.destroy();
SimpleTest.finish();