зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1217683 - Add sendIceCandidate and implement |close(aReason)| in TCPControlChannel. r=fabrice
This commit is contained in:
Родитель
04cd256752
Коммит
a647752f7e
|
@ -546,6 +546,13 @@ PresentationControllingInfo::GetAddress()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
PresentationControllingInfo::OnIceCandidate(const nsAString& aCandidate)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(false, "Should not receive ICE candidates.");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PresentationControllingInfo::OnGetAddress(const nsACString& aAddress)
|
PresentationControllingInfo::OnGetAddress(const nsACString& aAddress)
|
||||||
{
|
{
|
||||||
|
@ -851,6 +858,13 @@ PresentationPresentingInfo::OnAnswer(nsIPresentationChannelDescription* aDescrip
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
PresentationPresentingInfo::OnIceCandidate(const nsAString& aCandidate)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(false, "Should not receive ICE candidates.");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
PresentationPresentingInfo::NotifyOpened()
|
PresentationPresentingInfo::NotifyOpened()
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@ interface nsIPresentationChannelDescription: nsISupports
|
||||||
/*
|
/*
|
||||||
* The callbacks for events on control channel.
|
* The callbacks for events on control channel.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(d0cdc638-a9d5-4bcd-838c-3aed7c3f2a6b)]
|
[scriptable, uuid(96dd548f-7d0f-43c1-b1ad-28e666cf1e82)]
|
||||||
interface nsIPresentationControlChannelListener: nsISupports
|
interface nsIPresentationControlChannelListener: nsISupports
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -47,6 +47,12 @@ interface nsIPresentationControlChannelListener: nsISupports
|
||||||
*/
|
*/
|
||||||
void onAnswer(in nsIPresentationChannelDescription answer);
|
void onAnswer(in nsIPresentationChannelDescription answer);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback for receiving ICE candidate from remote endpoint.
|
||||||
|
* @param answer The received answer.
|
||||||
|
*/
|
||||||
|
void onIceCandidate(in DOMString candidate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The callback for notifying channel opened.
|
* The callback for notifying channel opened.
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +69,7 @@ interface nsIPresentationControlChannelListener: nsISupports
|
||||||
* The control channel for establishing RTCPeerConnection for a presentation
|
* The control channel for establishing RTCPeerConnection for a presentation
|
||||||
* session. SDP Offer/Answer will be exchanged through this interface.
|
* session. SDP Offer/Answer will be exchanged through this interface.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(2c8ec493-4e5b-4df7-bedc-7ab25af323f0)]
|
[scriptable, uuid(e60e208c-a9f5-4bc6-9a3e-47f3e4ae9c57)]
|
||||||
interface nsIPresentationControlChannel: nsISupports
|
interface nsIPresentationControlChannel: nsISupports
|
||||||
{
|
{
|
||||||
// The listener for handling events of this control channel.
|
// The listener for handling events of this control channel.
|
||||||
|
@ -71,26 +77,28 @@ interface nsIPresentationControlChannel: nsISupports
|
||||||
attribute nsIPresentationControlChannelListener listener;
|
attribute nsIPresentationControlChannelListener listener;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send offer to remote endpiont. |onOffer| should be invoked
|
* Send offer to remote endpoint. |onOffer| should be invoked on remote
|
||||||
* on remote endpoint.
|
* endpoint.
|
||||||
* @param offer The offer to send.
|
* @param offer The offer to send.
|
||||||
* @throws NS_ERROR_FAILURE on failure
|
* @throws NS_ERROR_FAILURE on failure
|
||||||
*/
|
*/
|
||||||
void sendOffer(in nsIPresentationChannelDescription offer);
|
void sendOffer(in nsIPresentationChannelDescription offer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send answer to remote endpiont. |onAnswer| should
|
* Send answer to remote endpoint. |onAnswer| should be invoked on remote
|
||||||
* be invoked on remote endpoint.
|
* endpoint.
|
||||||
* @param answer The answer to send.
|
* @param answer The answer to send.
|
||||||
* @throws NS_ERROR_FAILURE on failure
|
* @throws NS_ERROR_FAILURE on failure
|
||||||
*/
|
*/
|
||||||
void sendAnswer(in nsIPresentationChannelDescription answer);
|
void sendAnswer(in nsIPresentationChannelDescription answer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Notify the app-to-app connection is fully established. (Only used at the
|
* Send ICE candidate to remote endpoint. |onIceCandidate| should be invoked
|
||||||
* receiver side.)
|
* on remote endpoint.
|
||||||
|
* @param candidate The candidate to send
|
||||||
|
* @throws NS_ERROR_FAILURE on failure
|
||||||
*/
|
*/
|
||||||
void sendReceiverReady();
|
void sendIceCandidate(in DOMString candidate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close the transport channel.
|
* Close the transport channel.
|
||||||
|
|
|
@ -374,6 +374,14 @@ TCPControlChannel.prototype = {
|
||||||
this._sendMessage("answer", msg);
|
this._sendMessage("answer", msg);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
sendIceCandidate: function(aCandidate) {
|
||||||
|
let msg = {
|
||||||
|
type: "requestSession:IceCandidate",
|
||||||
|
presentationId: this.presentationId,
|
||||||
|
iceCandidate: aCandidate,
|
||||||
|
};
|
||||||
|
this._sendMessage("iceCandidate", msg);
|
||||||
|
},
|
||||||
// may throw an exception
|
// may throw an exception
|
||||||
_send: function(aMsg) {
|
_send: function(aMsg) {
|
||||||
DEBUG && log("TCPControlChannel - Send: " + JSON.stringify(aMsg, null, 2));
|
DEBUG && log("TCPControlChannel - Send: " + JSON.stringify(aMsg, null, 2));
|
||||||
|
@ -438,7 +446,7 @@ TCPControlChannel.prototype = {
|
||||||
onStopRequest: function(aRequest, aContext, aStatus) {
|
onStopRequest: function(aRequest, aContext, aStatus) {
|
||||||
DEBUG && log("TCPControlChannel - onStopRequest: " + aStatus
|
DEBUG && log("TCPControlChannel - onStopRequest: " + aStatus
|
||||||
+ " with role: " + this._direction);
|
+ " with role: " + this._direction);
|
||||||
this.close();
|
this.close(Cr.NS_OK);
|
||||||
this._notifyClosed(aStatus);
|
this._notifyClosed(aStatus);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -496,6 +504,14 @@ TCPControlChannel.prototype = {
|
||||||
this._onAnswer(aMsg.answer);
|
this._onAnswer(aMsg.answer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "requestSession:IceCandidate": {
|
||||||
|
this._listener.onIceCandidate(aMsg.iceCandidate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "requestSession:CloseReason": {
|
||||||
|
this._pendingCloseReason = aMsg.reason;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -573,7 +589,7 @@ TCPControlChannel.prototype = {
|
||||||
_notifyOpened: function() {
|
_notifyOpened: function() {
|
||||||
this._connected = true;
|
this._connected = true;
|
||||||
this._pendingClose = false;
|
this._pendingClose = false;
|
||||||
this._pendingCloseReason = null;
|
this._pendingCloseReason = Cr.NS_OK;
|
||||||
|
|
||||||
if (!this._listener) {
|
if (!this._listener) {
|
||||||
this._pendingOpen = true;
|
this._pendingOpen = true;
|
||||||
|
@ -591,6 +607,11 @@ TCPControlChannel.prototype = {
|
||||||
this._pendingOffer = null;
|
this._pendingOffer = null;
|
||||||
this._pendingAnswer = null;
|
this._pendingAnswer = null;
|
||||||
|
|
||||||
|
// Remote endpoint closes the control channel with abnormal reason.
|
||||||
|
if (aReason == Cr.NS_OK && this._pendingCloseReason != Cr.NS_OK) {
|
||||||
|
aReason = this._pendingCloseReason;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._listener) {
|
if (!this._listener) {
|
||||||
this._pendingClose = true;
|
this._pendingClose = true;
|
||||||
this._pendingCloseReason = aReason;
|
this._pendingCloseReason = aReason;
|
||||||
|
@ -602,9 +623,21 @@ TCPControlChannel.prototype = {
|
||||||
this._listener.notifyClosed(aReason);
|
this._listener.notifyClosed(aReason);
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function() {
|
close: function(aReason) {
|
||||||
DEBUG && log("TCPControlChannel - close");
|
DEBUG && log("TCPControlChannel - close with reason: " + aReason);
|
||||||
|
|
||||||
if (this._connected) {
|
if (this._connected) {
|
||||||
|
// default reason is NS_OK
|
||||||
|
if (typeof aReason !== "undefined" && aReason !== Cr.NS_OK) {
|
||||||
|
let msg = {
|
||||||
|
type: "requestSession:CloseReason",
|
||||||
|
presentationId: this.presentationId,
|
||||||
|
reason: aReason,
|
||||||
|
};
|
||||||
|
this._sendMessage("close", msg);
|
||||||
|
this._pendingCloseReason = aReason;
|
||||||
|
}
|
||||||
|
|
||||||
this._transport.setEventSink(null, null);
|
this._transport.setEventSink(null, null);
|
||||||
this._pump = null;
|
this._pump = null;
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@ TestDescription.prototype = {
|
||||||
const CONTROLLER_CONTROL_CHANNEL_PORT = 36777;
|
const CONTROLLER_CONTROL_CHANNEL_PORT = 36777;
|
||||||
const PRESENTER_CONTROL_CHANNEL_PORT = 36888;
|
const PRESENTER_CONTROL_CHANNEL_PORT = 36888;
|
||||||
|
|
||||||
|
var CLOSE_CONTROL_CHANNEL_REASON = Cr.NS_OK;
|
||||||
|
var candidate;
|
||||||
|
|
||||||
// presenter's presentation channel description
|
// presenter's presentation channel description
|
||||||
const OFFER_ADDRESS = '192.168.123.123';
|
const OFFER_ADDRESS = '192.168.123.123';
|
||||||
const OFFER_PORT = 123;
|
const OFFER_PORT = 123;
|
||||||
|
@ -98,13 +101,23 @@ function testPresentationServer() {
|
||||||
onAnswer: function(aAnswer) {
|
onAnswer: function(aAnswer) {
|
||||||
Assert.ok(false, 'get answer');
|
Assert.ok(false, 'get answer');
|
||||||
},
|
},
|
||||||
|
onIceCandidate: function(aCandidate) {
|
||||||
|
Assert.ok(true, '3. controllerControlChannel: get ice candidate, close channel');
|
||||||
|
let recvCandidate = JSON.parse(aCandidate);
|
||||||
|
for (let key in recvCandidate) {
|
||||||
|
if (typeof(recvCandidate[key]) !== "function") {
|
||||||
|
Assert.equal(recvCandidate[key], candidate[key], "key " + key + " should match.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
controllerControlChannel.close(CLOSE_CONTROL_CHANNEL_REASON);
|
||||||
|
},
|
||||||
notifyOpened: function() {
|
notifyOpened: function() {
|
||||||
Assert.equal(this.status, 'created', '0. controllerControlChannel: opened');
|
Assert.equal(this.status, 'created', '0. controllerControlChannel: opened');
|
||||||
this.status = 'opened';
|
this.status = 'opened';
|
||||||
},
|
},
|
||||||
notifyClosed: function(aReason) {
|
notifyClosed: function(aReason) {
|
||||||
Assert.equal(this.status, 'onOffer', '3. controllerControlChannel: closed');
|
Assert.equal(this.status, 'onOffer', '4. controllerControlChannel: closed');
|
||||||
Assert.equal(aReason, Cr.NS_OK, 'presenterControlChannel notify closed NS_OK');
|
Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, 'presenterControlChannel notify closed');
|
||||||
this.status = 'closed';
|
this.status = 'closed';
|
||||||
yayFuncs.controllerControlChannelClose();
|
yayFuncs.controllerControlChannelClose();
|
||||||
},
|
},
|
||||||
|
@ -132,15 +145,22 @@ function testPresentationServer() {
|
||||||
Assert.ok(false, 'get offer');
|
Assert.ok(false, 'get offer');
|
||||||
},
|
},
|
||||||
onAnswer: function(aAnswer) {
|
onAnswer: function(aAnswer) {
|
||||||
Assert.equal(this.status, 'opened', '2. presenterControlChannel: get answer, close channel');
|
Assert.equal(this.status, 'opened', '2. presenterControlChannel: get answer, send ICE candidate');
|
||||||
|
|
||||||
let answer = aAnswer.QueryInterface(Ci.nsIPresentationChannelDescription);
|
let answer = aAnswer.QueryInterface(Ci.nsIPresentationChannelDescription);
|
||||||
Assert.strictEqual(answer.tcpAddress.queryElementAt(0,Ci.nsISupportsCString).data,
|
Assert.strictEqual(answer.tcpAddress.queryElementAt(0,Ci.nsISupportsCString).data,
|
||||||
ANSWER_ADDRESS,
|
ANSWER_ADDRESS,
|
||||||
'expected answer address array');
|
'expected answer address array');
|
||||||
Assert.equal(answer.tcpPort, ANSWER_PORT, 'expected answer port');
|
Assert.equal(answer.tcpPort, ANSWER_PORT, 'expected answer port');
|
||||||
|
candidate = {
|
||||||
presenterControlChannel.close(Cr.NS_OK);
|
candidate: "1 1 UDP 1 127.0.0.1 34567 type host",
|
||||||
|
sdpMid: "helloworld",
|
||||||
|
sdpMLineIndex: 1
|
||||||
|
};
|
||||||
|
presenterControlChannel.sendIceCandidate(JSON.stringify(candidate));
|
||||||
|
},
|
||||||
|
onIceCandidate: function(aCandidate) {
|
||||||
|
Assert.ok(false, 'get ICE candidate');
|
||||||
},
|
},
|
||||||
notifyOpened: function() {
|
notifyOpened: function() {
|
||||||
Assert.equal(this.status, 'created', '0. presenterControlChannel: opened, send offer');
|
Assert.equal(this.status, 'created', '0. presenterControlChannel: opened, send offer');
|
||||||
|
@ -155,7 +175,7 @@ function testPresentationServer() {
|
||||||
},
|
},
|
||||||
notifyClosed: function(aReason) {
|
notifyClosed: function(aReason) {
|
||||||
this.status = 'closed';
|
this.status = 'closed';
|
||||||
Assert.equal(aReason, Cr.NS_OK, '3. presenterControlChannel notify closed NS_OK');
|
Assert.equal(aReason, CLOSE_CONTROL_CHANNEL_REASON, '4. presenterControlChannel notify closed');
|
||||||
yayFuncs.presenterControlChannelClose();
|
yayFuncs.presenterControlChannelClose();
|
||||||
},
|
},
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationControlChannelListener]),
|
||||||
|
@ -198,8 +218,15 @@ function shutdown()
|
||||||
tps.close();
|
tps.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test manually close control channel with NS_ERROR_FAILURE
|
||||||
|
function changeCloseReason() {
|
||||||
|
CLOSE_CONTROL_CHANNEL_REASON = Cr.NS_ERROR_FAILURE;
|
||||||
|
run_next_test();
|
||||||
|
}
|
||||||
|
|
||||||
add_test(loopOfferAnser);
|
add_test(loopOfferAnser);
|
||||||
add_test(setOffline);
|
add_test(setOffline);
|
||||||
|
add_test(changeCloseReason);
|
||||||
add_test(oneMoreLoop);
|
add_test(oneMoreLoop);
|
||||||
add_test(shutdown);
|
add_test(shutdown);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче