Bug 1284188 - use nsINetworkInfoService to obtain self IP address. r=smaug.

MozReview-Commit-ID: 1QwjrkV9cEk

--HG--
extra : rebase_source : 2aa7c8620505074aeba012de358d56edf0dc2af5
This commit is contained in:
Shih-Chiang Chien 2016-08-12 15:27:33 +08:00
parent 46ad65f8b8
commit 240af6bcf8
13 changed files with 115 additions and 527 deletions

View File

@ -648,22 +648,15 @@ PresentationControllingInfo::GetAddress()
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
// TODO Get host IP via other platforms.
nsCOMPtr<nsINetworkInfoService> networkInfo = do_GetService(NETWORKINFOSERVICE_CONTRACT_ID);
MOZ_ASSERT(networkInfo);
NS_DispatchToMainThread(
NewRunnableMethod<nsCString>(
this,
&PresentationControllingInfo::OnGetAddress,
EmptyCString()));
nsresult rv = networkInfo->ListNetworkAddresses(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
#endif
return NS_OK;
@ -952,6 +945,50 @@ PresentationControllingInfo::Reconnect(nsIPresentationServiceCallback* aCallback
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
*

View File

@ -13,6 +13,7 @@
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/RefPtr.h"
#include "nsCOMPtr.h"
#include "nsINetworkInfoService.h"
#include "nsIPresentationControlChannel.h"
#include "nsIPresentationDevice.h"
#include "nsIPresentationListener.h"
@ -171,11 +172,13 @@ protected:
// 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)

View File

@ -328,6 +328,12 @@ 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;
}

View File

@ -374,7 +374,7 @@ function tearDown() {
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);

View File

@ -8,6 +8,7 @@
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);
@ -18,143 +19,8 @@ function debug(str) {
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]),
@ -183,7 +49,9 @@ const mockControlChannelOfSender = {
.notifyReconnected();
},
sendOffer: function(offer) {
sendAsyncMessage('offer-sent');
Services.tm.mainThread.dispatch(() => {
mockControlChannelOfReceiver.onOffer(offer);
}, Ci.nsIThread.DISPATCH_NORMAL);
},
onAnswer: function(answer) {
this._listener
@ -247,10 +115,9 @@ const mockControlChannelOfReceiver = {
.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) {
@ -359,12 +226,6 @@ function initMockAndListener() {
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));
@ -427,17 +288,6 @@ function initMockAndListener() {
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);
@ -459,15 +309,13 @@ 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;
@ -477,7 +325,7 @@ function teardown() {
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);

View File

@ -157,7 +157,7 @@ function loadPrivilegedScriptTest() {
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);

View File

@ -5,6 +5,7 @@ support-files =
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
@ -30,7 +31,7 @@ support-files =
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

View File

@ -84,18 +84,6 @@ function setup() {
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();
}

View File

@ -1,18 +1,7 @@
<!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">
/* 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';
@ -54,6 +43,8 @@ function setup() {
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) {
@ -90,18 +81,6 @@ function setup() {
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();
}
@ -252,18 +231,6 @@ function testReconnect() {
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) => {
@ -323,7 +290,3 @@ SpecialPowers.pushPermissions([
["dom.mozBrowserFramesEnabled", true]]},
runTests);
});
</script>
</body>
</html>

View File

@ -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>

View File

@ -12,267 +12,7 @@
<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>

View File

@ -78,18 +78,6 @@ function setup() {
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();
}

View File

@ -83,18 +83,6 @@ function setup() {
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();
}
@ -139,23 +127,31 @@ function testStartConnection() {
}
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() {