Bug 1209744 - Implement canTrickleIceCandidates attribute, r=bwc, r=khuey

--HG--
extra : rebase_source : bfdf5073bec5fd6cb9689701fb1df6ee841362d6
extra : amend_source : e6ec6e7ed24a24b7dfcc8b60eda38d3d2a00d2f1
This commit is contained in:
Martin Thomson 2015-10-01 12:52:00 +02:00
parent ee543a3018
commit 840a4a7b4e
6 changed files with 109 additions and 43 deletions

View File

@ -341,6 +341,10 @@ function RTCPeerConnection() {
this._localType = null;
this._remoteType = null;
// http://rtcweb-wg.github.io/jsep/#rfc.section.4.1.9
// canTrickle == null means unknown; when a remote description is received it
// is set to true or false based on the presence of the "trickle" ice-option
this._canTrickle = null;
// States
this._iceGatheringState = this._iceConnectionState = "new";
@ -919,7 +923,7 @@ RTCPeerConnection.prototype = {
this._onSetRemoteDescriptionSuccess = resolve;
this._onSetRemoteDescriptionFailure = reject;
this._impl.setRemoteDescription(type, desc.sdp);
}));
})).then(() => { this._updateCanTrickle(); });
if (desc.type === "rollback") {
return setRem;
@ -947,9 +951,37 @@ RTCPeerConnection.prototype = {
);
},
updateIce: function(config) {
throw new this._win.DOMException("updateIce not yet implemented",
"NotSupportedError");
get canTrickleIceCandidates() {
return this._canTrickle;
},
_updateCanTrickle: function() {
let containsTrickle = section => {
let lines = section.toLowerCase().split(/(?:\r\n?|\n)/);
return lines.some(line => {
let prefix = "a=ice-options:";
if (line.substring(0, prefix.length) !== prefix) {
return false;
}
let tokens = line.substring(prefix.length).split(" ");
return tokens.some(x => x === "trickle");
});
};
let desc = null;
try {
// The getter for remoteDescription can throw if the pc is closed.
desc = this.remoteDescription;
} catch (e) {}
if (!desc) {
this._canTrickle = null;
return;
}
let sections = desc.sdp.split(/(?:\r\n?|\n)m=/);
let topSection = sections.shift();
this._canTrickle =
containsTrickle(topSection) || sections.every(containsTrickle);
},
addIceCandidate: function(c, onSuccess, onError) {

View File

@ -2,6 +2,11 @@
* 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/. */
function removeTrickleOption(desc) {
var sdp = desc.sdp.replace(/\r\na=ice-options:trickle\r\n/, "\r\n");
return new mozRTCSessionDescription({ type: desc.type, sdp: sdp });
}
function makeOffererNonTrickle(chain) {
chain.replace('PC_LOCAL_SETUP_ICE_HANDLER', [
function PC_LOCAL_SETUP_NOTRICKLE_ICE_HANDLER(test) {
@ -14,7 +19,7 @@ function makeOffererNonTrickle(chain) {
chain.replace('PC_REMOTE_GET_OFFER', [
function PC_REMOTE_GET_FULL_OFFER(test) {
return test.pcLocal.endOfTrickleIce.then(() => {
test._local_offer = test.pcLocal.localDescription;
test._local_offer = removeTrickleOption(test.pcLocal.localDescription);
test._offer_constraints = test.pcLocal.constraints;
test._offer_options = test.pcLocal.offerOptions;
});
@ -24,11 +29,14 @@ function makeOffererNonTrickle(chain) {
function PC_REMOTE_REQUIRE_REMOTE_SDP_CANDIDATES(test) {
info("test.pcLocal.localDescription.sdp: " + JSON.stringify(test.pcLocal.localDescription.sdp));
info("test._local_offer.sdp" + JSON.stringify(test._local_offer.sdp));
is(test.pcRemote._pc.canTrickleIceCandidates, false,
"Remote thinks that trickle isn't supported");
ok(!test.localRequiresTrickleIce, "Local does NOT require trickle");
ok(test._local_offer.sdp.includes("a=candidate"), "offer has ICE candidates")
ok(test._local_offer.sdp.includes("a=end-of-candidates"), "offer has end-of-candidates");
}
]);
chain.remove('PC_REMOTE_CHECK_CAN_TRICKLE_SYNC');
}
function makeAnswererNonTrickle(chain) {
@ -43,7 +51,7 @@ function makeAnswererNonTrickle(chain) {
chain.replace('PC_LOCAL_GET_ANSWER', [
function PC_LOCAL_GET_FULL_ANSWER(test) {
return test.pcRemote.endOfTrickleIce.then(() => {
test._remote_answer = test.pcRemote.localDescription;
test._remote_answer = removeTrickleOption(test.pcRemote.localDescription);
test._answer_constraints = test.pcRemote.constraints;
});
}
@ -52,9 +60,12 @@ function makeAnswererNonTrickle(chain) {
function PC_LOCAL_REQUIRE_REMOTE_SDP_CANDIDATES(test) {
info("test.pcRemote.localDescription.sdp: " + JSON.stringify(test.pcRemote.localDescription.sdp));
info("test._remote_answer.sdp" + JSON.stringify(test._remote_answer.sdp));
is(test.pcLocal._pc.canTrickleIceCandidates, false,
"Local thinks that trickle isn't supported");
ok(!test.remoteRequiresTrickleIce, "Remote does NOT require trickle");
ok(test._remote_answer.sdp.includes("a=candidate"), "answer has ICE candidates")
ok(test._remote_answer.sdp.includes("a=end-of-candidates"), "answer has end-of-candidates");
}
]);
chain.remove('PC_LOCAL_CHECK_CAN_TRICKLE_SYNC');
}

View File

@ -193,6 +193,15 @@ var commandsPeerConnectionInitial = [
"Initial remote ICE connection state is 'new'");
},
function PC_LOCAL_CHECK_INITIAL_CAN_TRICKLE_SYNC(test) {
is(test.pcLocal._pc.canTrickleIceCandidates, null,
"Local trickle status should start out unknown");
},
function PC_REMOTE_CHECK_INITIAL_CAN_TRICKLE_SYNC(test) {
is(test.pcRemote._pc.canTrickleIceCandidates, null,
"Remote trickle status should start out unknown");
},
];
var commandsGetUserMedia = [
@ -305,6 +314,11 @@ var commandsPeerConnectionOfferAnswer = [
});
},
function PC_REMOTE_CHECK_CAN_TRICKLE_SYNC(test) {
is(test.pcRemote._pc.canTrickleIceCandidates, true,
"Remote thinks that local can trickle");
},
function PC_LOCAL_SANE_LOCAL_SDP(test) {
test.pcLocal.localRequiresTrickleIce =
sdputils.verifySdp(test._local_offer, "offer",
@ -376,6 +390,11 @@ var commandsPeerConnectionOfferAnswer = [
test.testOptions);
},
function PC_LOCAL_CHECK_CAN_TRICKLE_SYNC(test) {
is(test.pcLocal._pc.canTrickleIceCandidates, true,
"Local thinks that remote can trickle");
},
function PC_LOCAL_WAIT_FOR_ICE_CONNECTED(test) {
return waitForIceConnected(test, test.pcLocal);
},

View File

@ -6,41 +6,45 @@
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "952145",
title: "Rollback remote offer"
});
createHTML({
bug: "952145",
title: "Rollback remote offer"
});
var test;
runNetworkTest(function (options) {
test = new PeerConnectionTest(options);
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.chain.removeAfter('PC_REMOTE_SET_REMOTE_DESCRIPTION');
test.chain.append([
function PC_REMOTE_ROLLBACK(test) {
return test.setRemoteDescription(
test.pcRemote,
new RTCSessionDescription({ type: "rollback" }),
STABLE);
},
var test;
runNetworkTest(function (options) {
test = new PeerConnectionTest(options);
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.chain.removeAfter('PC_REMOTE_CHECK_CAN_TRICKLE_SYNC');
test.chain.append([
function PC_REMOTE_ROLLBACK(test) {
return test.setRemoteDescription(
test.pcRemote,
new RTCSessionDescription({ type: "rollback" }),
STABLE);
},
function PC_LOCAL_ROLLBACK(test) {
return test.setLocalDescription(
test.pcLocal,
new RTCSessionDescription({ type: "rollback", sdp: ""}),
STABLE);
},
function PC_REMOTE_CHECK_CAN_TRICKLE_REVERT_SYNC(test) {
is(test.pcRemote._pc.canTrickleIceCandidates, null,
"Remote canTrickleIceCandidates is reverted to null");
},
// Rolling back should shut down gathering
function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
return test.pcLocal.endOfTrickleIce;
},
]);
test.chain.append(commandsPeerConnectionOfferAnswer);
test.run();
});
function PC_LOCAL_ROLLBACK(test) {
return test.setLocalDescription(
test.pcLocal,
new RTCSessionDescription({ type: "rollback", sdp: "" }),
STABLE);
},
// Rolling back should shut down gathering
function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
return test.pcLocal.endOfTrickleIce;
},
]);
test.chain.append(commandsPeerConnectionOfferAnswer);
test.run();
});
</script>
</pre>
</body>
</html>

View File

@ -4,7 +4,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCPeerConnection
* http://w3c.github.io/webrtc-pc/#interface-definition
*/
callback RTCSessionDescriptionCallback = void (RTCSessionDescription sdp);
@ -103,8 +103,8 @@ interface RTCPeerConnection : EventTarget {
readonly attribute RTCSessionDescription? localDescription;
readonly attribute RTCSessionDescription? remoteDescription;
readonly attribute RTCSignalingState signalingState;
void updateIce (optional RTCConfiguration configuration);
Promise<void> addIceCandidate (RTCIceCandidate candidate);
readonly attribute boolean? canTrickleIceCandidates;
readonly attribute RTCIceGatheringState iceGatheringState;
readonly attribute RTCIceConnectionState iceConnectionState;
[Pref="media.peerconnection.identity.enabled"]

View File

@ -13,7 +13,7 @@
expected: FAIL
[RTCPeerConnection interface: attribute canTrickleIceCandidates]
expected: FAIL
expected: PASS
[RTCPeerConnection interface: attribute onicegatheringstatechange]
expected: FAIL
@ -109,7 +109,7 @@
expected: FAIL
[RTCPeerConnection interface: pc must inherit property "canTrickleIceCandidates" with the proper type (14)]
expected: FAIL
expected: PASS
[RTCPeerConnection interface: pc must inherit property "setConfiguration" with the proper type (16)]
expected: FAIL
@ -172,7 +172,7 @@
expected: FAIL
[RTCPeerConnection interface: attribute canTrickleIceCandidates]
expected: FAIL
expected: PASS
[RTCPeerConnection interface: attribute onicegatheringstatechange]
expected: FAIL
@ -244,7 +244,7 @@
expected: FAIL
[RTCPeerConnection interface: pc must inherit property "canTrickleIceCandidates" with the proper type (11)]
expected: FAIL
expected: PASS
[RTCPeerConnection interface: pc must inherit property "onnegotiationneeded" with the proper type (14)]
expected: FAIL