Bug 1322503 - Hyphenate rtc stats type as per spec. r?jib
MozReview-Commit-ID: 8zYkt8gOpsM
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -296,23 +296,30 @@ RTCStatsReport.prototype = {
return this.__DOM_IMPL__.__set(aKey, aObj);
},
// TODO: Remove legacy API eventually
//
// Since maplike is recent, we still also make the stats available as legacy
// enumerable read-only properties directly on our content-facing object.
// Must be called after our webidl sandwich is made.
+ _specToLegacyFieldMapping: {
+ 'inbound-rtp' : 'inboundrtp',
+ 'outbound-rtp':'outboundrtp',
+ 'candidate-pair':'candidatepair',
+ 'local-candidate':'localcandidate',
+ 'remote-candidate':'remotecandidate'
+ },
makeStatsPublic: function(warnNullable) {
let legacyProps = {};
for (let key in this._report) {
+ this.setInternal(key, Cu.cloneInto(this._report[key], this._win));
let value = Cu.cloneInto(this._report[key], this._win);
- this.setInternal(key, value);
-
+ value.type = this._specToLegacyFieldMapping[value.type] || value.type;
legacyProps[key] = {
enumerable: true, configurable: false,
get: Cu.exportFunction(function() {
if (warnNullable.warn) {
warnNullable.warn();
warnNullable.warn = null;
}
return value;
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1418,24 +1418,24 @@ PeerConnectionWrapper.prototype = {
* @returns {Promise}
* A promise that resolves when media is flowing.
*/
waitForRtpFlow(track) {
var hasFlow = (stats, retries) => {
info("Checking for stats in " + JSON.stringify(stats) + " for " + track.kind
+ " track " + track.id + ", retry number " + retries);
var rtp = stats.get([...Object.keys(stats)].find(key =>
- !stats.get(key).isRemote && stats.get(key).type.endsWith("boundrtp")));
+ !stats.get(key).isRemote && stats.get(key).type.endsWith("bound-rtp")));
if (!rtp) {
return false;
}
info("Should have RTP stats for track " + track.id);
info("RTP stats: "+JSON.stringify(rtp));
- var nrPackets = rtp[rtp.type == "outboundrtp" ? "packetsSent"
+ var nrPackets = rtp[rtp.type == "outbound-rtp" ? "packetsSent"
: "packetsReceived"];
info("Track " + track.id + " has " + nrPackets + " " +
rtp.type + " RTP packets.");
return nrPackets > 0;
};
// Time between stats checks
var retryInterval = 500;
@@ -1596,38 +1596,38 @@ PeerConnectionWrapper.prototype = {
}
}
if (res.isRemote) {
continue;
}
counters[res.type] = (counters[res.type] || 0) + 1;
switch (res.type) {
- case "inboundrtp":
- case "outboundrtp": {
+ case "inbound-rtp":
+ case "outbound-rtp": {
// ssrc is a 32 bit number returned as a string by spec
ok(res.ssrc.length > 0, "Ssrc has length");
ok(res.ssrc.length < 11, "Ssrc not lengthy");
ok(!/[^0-9]/.test(res.ssrc), "Ssrc numeric");
ok(parseInt(res.ssrc) < Math.pow(2,32), "Ssrc within limits");
- if (res.type == "outboundrtp") {
+ if (res.type == "outbound-rtp") {
ok(res.packetsSent !== undefined, "Rtp packetsSent");
// We assume minimum payload to be 1 byte (guess from RFC 3550)
ok(res.bytesSent >= res.packetsSent, "Rtp bytesSent");
} else {
ok(res.packetsReceived !== undefined, "Rtp packetsReceived");
ok(res.bytesReceived >= res.packetsReceived, "Rtp bytesReceived");
}
if (res.remoteId) {
- var rem = stats[res.remoteId];
+ var rem = stats.get(res.remoteId);
ok(rem.isRemote, "Remote is rtcp");
ok(rem.remoteId == res.id, "Remote backlink match");
- if(res.type == "outboundrtp") {
- ok(rem.type == "inboundrtp", "Rtcp is inbound");
+ if(res.type == "outbound-rtp") {
+ ok(rem.type == "inbound-rtp", "Rtcp is inbound");
ok(rem.packetsReceived !== undefined, "Rtcp packetsReceived");
ok(rem.packetsLost !== undefined, "Rtcp packetsLost");
ok(rem.bytesReceived >= rem.packetsReceived, "Rtcp bytesReceived");
if (false) { // Bug 1325430 if (!this.disableRtpCountChecking) {
// no guarantee which one is newer!
// Note: this must change when we add a timestamp field to remote RTCP reports
// and make rem.timestamp be the reception time
if (res.timestamp >= rem.timestamp) {
@@ -1639,77 +1639,85 @@ PeerConnectionWrapper.prototype = {
// Else we may have received more than outdated Rtcp packetsSent
ok(rem.bytesReceived <= res.bytesSent, "No more than sent bytes");
}
ok(rem.jitter !== undefined, "Rtcp jitter");
ok(rem.mozRtt !== undefined, "Rtcp rtt");
ok(rem.mozRtt >= 0, "Rtcp rtt " + rem.mozRtt + " >= 0");
ok(rem.mozRtt < 60000, "Rtcp rtt " + rem.mozRtt + " < 1 min");
} else {
- ok(rem.type == "outboundrtp", "Rtcp is outbound");
+ ok(rem.type == "outbound-rtp", "Rtcp is outbound");
ok(rem.packetsSent !== undefined, "Rtcp packetsSent");
// We may have received more than outdated Rtcp packetsSent
ok(rem.bytesSent >= rem.packetsSent, "Rtcp bytesSent");
}
ok(rem.ssrc == res.ssrc, "Remote ssrc match");
} else {
info("No rtcp info received yet");
}
}
break;
}
}
+ var legacyToSpecMapping = {
+ 'inboundrtp':'inbound-rtp',
+ 'outboundrtp':'outbound-rtp',
+ 'candidatepair':'candidate-pair',
+ 'localcandidate':'local-candidate',
+ 'remotecandidate':'remote-candidate'
+ };
// Use legacy way of enumerating stats
var counters2 = {};
for (let key in stats) {
if (!stats.hasOwnProperty(key)) {
continue;
}
var res = stats[key];
+ var type = legacyToSpecMapping[res.type] || res.type;
if (!res.isRemote) {
- counters2[res.type] = (counters2[res.type] || 0) + 1;
+ counters2[type] = (counters2[type] || 0) + 1;
}
}
is(JSON.stringify(counters), JSON.stringify(counters2),
"Spec and legacy variant of RTCStatsReport enumeration agree");
var nin = Object.keys(this.expectedRemoteTrackInfoById).length;
var nout = Object.keys(this.expectedLocalTrackInfoById).length;
var ndata = this.dataChannels.length;
- // TODO(Bug 957145): Restore stronger inboundrtp test once Bug 948249 is fixed
- //is((counters["inboundrtp"] || 0), nin, "Have " + nin + " inboundrtp stat(s)");
- ok((counters.inboundrtp || 0) >= nin, "Have at least " + nin + " inboundrtp stat(s) *");
+ // TODO(Bug 957145): Restore stronger inbound-rtp test once Bug 948249 is fixed
+ //is((counters["inbound-rtp"] || 0), nin, "Have " + nin + " inbound-rtp stat(s)");
+ ok((counters["inbound-rtp"] || 0) >= nin, "Have at least " + nin + " inbound-rtp stat(s) *");
- is(counters.outboundrtp || 0, nout, "Have " + nout + " outboundrtp stat(s)");
+ is(counters["outbound-rtp"] || 0, nout, "Have " + nout + " outbound-rtp stat(s)");
- var numLocalCandidates = counters.localcandidate || 0;
- var numRemoteCandidates = counters.remotecandidate || 0;
+ var numLocalCandidates = counters["local-candidate"] || 0;
+ var numRemoteCandidates = counters["remote-candidate"] || 0;
// If there are no tracks, there will be no stats either.
if (nin + nout + ndata > 0) {
- ok(numLocalCandidates, "Have localcandidate stat(s)");
- ok(numRemoteCandidates, "Have remotecandidate stat(s)");
+ ok(numLocalCandidates, "Have local-candidate stat(s)");
+ ok(numRemoteCandidates, "Have remote-candidate stat(s)");
} else {
- is(numLocalCandidates, 0, "Have no localcandidate stats");
- is(numRemoteCandidates, 0, "Have no remotecandidate stats");
+ is(numLocalCandidates, 0, "Have no local-candidate stats");
+ is(numRemoteCandidates, 0, "Have no remote-candidate stats");
}
},
/**
* Compares the Ice server configured for this PeerConnectionWrapper
* with the ICE candidates received in the RTCP stats.
*
* @param {object} stats
* The stats to be verified for relayed vs. direct connection.
*/
checkStatsIceConnectionType : function(stats, expectedLocalCandidateType) {
let lId;
let rId;
for (let stat of stats.values()) {
- if (stat.type == "candidatepair" && stat.selected) {
+ if (stat.type == "candidate-pair" && stat.selected) {
lId = stat.localCandidateId;
rId = stat.remoteCandidateId;
break;
}
}
isnot(lId, undefined, "Got local candidate ID " + lId + " for selected pair");
isnot(rId, undefined, "Got remote candidate ID " + rId + " for selected pair");
let lCand = stats.get(lId);
@@ -1750,18 +1758,18 @@ PeerConnectionWrapper.prototype = {
* @param {object} counters
* The counters for media and data tracks based on constraints
* @param {object} testOptions
* The test options object from the PeerConnectionTest
*/
checkStatsIceConnections : function(stats,
offerConstraintsList, offerOptions, testOptions) {
var numIceConnections = 0;
- Object.keys(stats).forEach(key => {
- if ((stats[key].type === "candidatepair") && stats[key].selected) {
+ stats.forEach(stat => {
+ if ((stat.type === "candidate-pair") && stat.selected) {
numIceConnections += 1;
}
});
info("ICE connections according to stats: " + numIceConnections);
isnot(numIceConnections, 0, "Number of ICE connections according to stats is not zero");
if (testOptions.bundle) {
if (testOptions.rtcpmux) {
is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -85,22 +85,22 @@ function waitForAnIceCandidate(pc) {
function checkTrackStats(pc, rtpSenderOrReceiver, outbound) {
var track = rtpSenderOrReceiver.track;
var audio = (track.kind == "audio");
var msg = pc + " stats " + (outbound ? "outbound " : "inbound ") +
(audio ? "audio" : "video") + " rtp track id " + track.id;
return pc.getStats(track).then(stats => {
ok(pc.hasStat(stats, {
- type: outbound ? "outboundrtp" : "inboundrtp",
+ type: outbound ? "outbound-rtp" : "inbound-rtp",
isRemote: false,
mediaType: audio ? "audio" : "video"
}), msg + " - found expected stats");
ok(!pc.hasStat(stats, {
- type: outbound ? "inboundrtp" : "outboundrtp",
+ type: outbound ? "inbound-rtp" : "outbound-rtp",
isRemote: false
}), msg + " - did not find extra stats with wrong direction");
ok(!pc.hasStat(stats, {
mediaType: audio ? "video" : "audio"
}), msg + " - did not find extra stats with wrong media type");
});
}
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -67,17 +67,17 @@ struct ParamTraits<mozilla::dom::Sequenc
return ReadParam(aMsg, aIter, dynamic_cast<FallibleTArray<T>*>(aResult));
}
};
template<>
struct ParamTraits<mozilla::dom::RTCStatsType> :
public ContiguousEnumSerializer<
mozilla::dom::RTCStatsType,
- mozilla::dom::RTCStatsType::Inboundrtp,
+ mozilla::dom::RTCStatsType::Inbound_rtp,
mozilla::dom::RTCStatsType::EndGuard_>
{};
template<>
struct ParamTraits<mozilla::dom::RTCStatsIceCandidatePairState> :
public ContiguousEnumSerializer<
mozilla::dom::RTCStatsIceCandidatePairState,
mozilla::dom::RTCStatsIceCandidatePairState::Frozen,
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -4,24 +4,24 @@
* 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#rtcstatsreport-object
* http://www.w3.org/2011/04/webrtc/wiki/Stats
*/
enum RTCStatsType {
- "inboundrtp",
- "outboundrtp",
+ "inbound-rtp",
+ "outbound-rtp",
"session",
"track",
"transport",
- "candidatepair",
- "localcandidate",
- "remotecandidate"
+ "candidate-pair",
+ "local-candidate",
+ "remote-candidate"
};
dictionary RTCStats {
DOMHighResTimeStamp timestamp;
RTCStatsType type;
DOMString id;
};
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -3680,17 +3680,17 @@ static void ToRTCIceCandidateStats(
cand.mTimestamp.Construct(now);
cand.mCandidateType.Construct(
RTCStatsIceCandidateType(c->type));
cand.mIpAddress.Construct(
NS_ConvertASCIItoUTF16(c->cand_addr.host.c_str()));
cand.mPortNumber.Construct(c->cand_addr.port);
cand.mTransport.Construct(
NS_ConvertASCIItoUTF16(c->cand_addr.transport.c_str()));
- if (candidateType == RTCStatsType::Localcandidate) {
+ if (candidateType == RTCStatsType::Local_candidate) {
cand.mMozLocalTransport.Construct(
NS_ConvertASCIItoUTF16(c->local_addr.transport.c_str()));
}
report->mIceCandidateStats.Value().AppendElement(cand, fallible);
}
}
static void RecordIceStats_s(
@@ -3714,39 +3714,39 @@ static void RecordIceStats_s(
NS_ConvertASCIItoUTF16 remoteCodeword(p->remote.codeword.c_str());
// Only expose candidate-pair statistics to chrome, until we've thought
// through the implications of exposing it to content.
RTCIceCandidatePairStats s;
s.mId.Construct(codeword);
s.mComponentId.Construct(componentId);
s.mTimestamp.Construct(now);
- s.mType.Construct(RTCStatsType::Candidatepair);
+ s.mType.Construct(RTCStatsType::Candidate_pair);
s.mLocalCandidateId.Construct(localCodeword);
s.mRemoteCandidateId.Construct(remoteCodeword);
s.mNominated.Construct(p->nominated);
s.mPriority.Construct(p->priority);
s.mSelected.Construct(p->selected);
s.mState.Construct(RTCStatsIceCandidatePairState(p->state));
report->mIceCandidatePairStats.Value().AppendElement(s, fallible);
}
std::vector<NrIceCandidate> candidates;
if (NS_SUCCEEDED(mediaStream.GetLocalCandidates(&candidates))) {
ToRTCIceCandidateStats(candidates,
- RTCStatsType::Localcandidate,
+ RTCStatsType::Local_candidate,
componentId,
now,
report);
}
candidates.clear();
if (NS_SUCCEEDED(mediaStream.GetRemoteCandidates(&candidates))) {
ToRTCIceCandidateStats(candidates,
- RTCStatsType::Remotecandidate,
+ RTCStatsType::Remote_candidate,
componentId,
now,
report);
}
}
nsresult
PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) {
@@ -3790,17 +3790,17 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
&packetsReceived,
&bytesReceived,
&packetsLost,
&rtt)) {
remoteId = NS_LITERAL_STRING("outbound_rtcp_") + idstr;
RTCInboundRTPStreamStats s;
s.mTimestamp.Construct(timestamp);
s.mId.Construct(remoteId);
- s.mType.Construct(RTCStatsType::Inboundrtp);
+ s.mType.Construct(RTCStatsType::Inbound_rtp);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
s.mMediaType.Construct(mediaType);
s.mJitter.Construct(double(jitterMs)/1000);
s.mRemoteId.Construct(localId);
s.mIsRemote = true;
s.mPacketsReceived.Construct(packetsReceived);
@@ -3811,17 +3811,17 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
fallible);
}
}
// Then, fill in local side (with cross-link to remote only if present)
{
RTCOutboundRTPStreamStats s;
s.mTimestamp.Construct(query->now);
s.mId.Construct(localId);
- s.mType.Construct(RTCStatsType::Outboundrtp);
+ s.mType.Construct(RTCStatsType::Outbound_rtp);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
s.mMediaType.Construct(mediaType);
s.mRemoteId.Construct(remoteId);
s.mIsRemote = false;
s.mPacketsSent.Construct(mp.rtp_packets_sent());
s.mBytesSent.Construct(mp.rtp_bytes_sent());
@@ -3864,34 +3864,34 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
uint32_t packetsSent;
uint64_t bytesSent;
if (mp.Conduit()->GetRTCPSenderReport(×tamp,
&packetsSent, &bytesSent)) {
remoteId = NS_LITERAL_STRING("inbound_rtcp_") + idstr;
RTCOutboundRTPStreamStats s;
s.mTimestamp.Construct(timestamp);
s.mId.Construct(remoteId);
- s.mType.Construct(RTCStatsType::Outboundrtp);
+ s.mType.Construct(RTCStatsType::Outbound_rtp);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
s.mMediaType.Construct(mediaType);
s.mRemoteId.Construct(localId);
s.mIsRemote = true;
s.mPacketsSent.Construct(packetsSent);
s.mBytesSent.Construct(bytesSent);
query->report->mOutboundRTPStreamStats.Value().AppendElement(s,
fallible);
}
}
// Then, fill in local side (with cross-link to remote only if present)
RTCInboundRTPStreamStats s;
s.mTimestamp.Construct(query->now);
s.mId.Construct(localId);
- s.mType.Construct(RTCStatsType::Inboundrtp);
+ s.mType.Construct(RTCStatsType::Inbound_rtp);
if (ssrc.Length()) {
s.mSsrc.Construct(ssrc);
}
s.mMediaType.Construct(mediaType);
unsigned int jitterMs, packetsLost;
if (mp.Conduit()->GetRTPStats(&jitterMs, &packetsLost)) {
s.mJitter.Construct(double(jitterMs)/1000);
s.mPacketsLost.Construct(packetsLost);
--- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
+++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
@@ -1076,17 +1076,17 @@ static void StoreLongTermICEStatisticsIm
static const uint32_t kLocalShift = 16;
static const uint32_t kSrflxShift = 3;
static const uint32_t kRelayShift = 6;
static const uint32_t kPrflxShift = 9;
uint32_t candBitmask = GetCandidateIpAndTransportMask(&cand);
// Note: shift values need to result in the above enum table
- if (cand.mType.Value() == RTCStatsType::Localcandidate) {
+ if (cand.mType.Value() == RTCStatsType::Local_candidate) {
candBitmask <<= kLocalShift;
}
if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Serverreflexive) {
candBitmask <<= kSrflxShift;
} else if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Relayed) {
candBitmask <<= kRelayShift;
} else if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Peerreflexive) {