Bug 1435789: implement relayProtocol for localcandidate stats r=smaug,ng
authorPhilipp Hancke <fippo@appear.in>
Sun, 07 Oct 2018 07:42:48 +0000
changeset 499604 b32ff85f22247b5f7512e672e2d77d41d38a397a
parent 499603 89f4156c07a5ab35fd1d9a97354341bee9d11e2a
child 499605 7f30799c0c324bbafe48e9ee63a9a8cc50215037
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, ng
bugs1435789
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1435789: implement relayProtocol for localcandidate stats r=smaug,ng relayProtocol is the standardized variant of mozLocalTransport. Spec: https://w3c.github.io/webrtc-stats/#dom-rtcicecandidatestats-relayprotocol IDL: https://w3c.github.io/webrtc-stats/#icecandidate-dict* Differential Revision: https://phabricator.services.mozilla.com/D3428
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/test_peerConnection_stats.html
dom/media/tests/mochitest/test_peerConnection_stats_relayProtocol.html
dom/media/webrtc/WebrtcGlobal.h
dom/webidl/RTCStatsReport.webidl
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
toolkit/content/aboutwebrtc/aboutWebrtc.js
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -342,16 +342,18 @@ skip-if = (android_version == '18') # an
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_threeUnbundledConnections.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_selftest.html]
 # Bug 1227781: Crash with bogus TURN server.
 [test_peerConnection_bug1227781.html]
 [test_peerConnection_stats.html]
 skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
+[test_peerConnection_stats_relayProtocol.html]
+skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
 [test_peerConnection_sender_and_receiver_stats.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_trackless_sender_stats.html]
 skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_verifyDescriptions.html]
 skip-if = (android_version == '18')
 [test_fingerprinting_resistance.html]
 [test_getUserMedia_nonDefaultRate.html]
--- a/dom/media/tests/mochitest/test_peerConnection_stats.html
+++ b/dom/media/tests/mochitest/test_peerConnection_stats.html
@@ -576,19 +576,18 @@ var PC_LOCAL_TEST_LOCAL_STATS = test => 
 
 var PC_REMOTE_TEST_REMOTE_STATS = test => {
   return waitForSyncedRtcp(test.pcRemote).then(stats => {
     checkExpectedFields(stats);
     pedanticChecks(stats);
   });
 }
 
-var test;
 runNetworkTest(function (options) {
-  test = new PeerConnectionTest(options);
+  const test = new PeerConnectionTest(options);
 
   test.chain.insertAfter("PC_LOCAL_WAIT_FOR_MEDIA_FLOW",
     [PC_LOCAL_TEST_LOCAL_STATS]);
 
   test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW",
     [PC_REMOTE_TEST_REMOTE_STATS]);
 
   test.setMediaConstraints([{audio: true}, {video: true}],
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_stats_relayProtocol.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="nonTrickleIce.js"></script>
+  <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    bug: "1435789",
+    title: "WebRTC local-candidate relayProtocol stats attribute"
+  });
+var PC_LOCAL_TEST_LOCAL_STATS_RELAYCANDIDATE = test => {
+  return test.pcLocal.getStats().then(stats => {
+    let haveRelayProtocol = {};
+    for (let [k, v] of stats) {
+      if (v.type == "local-candidate") {
+        haveRelayProtocol[v.candidateType + "-" + v.relayProtocol] = v.relayProtocol;
+      }
+    }
+    is(haveRelayProtocol["host-undefined"], undefined, "relayProtocol not set for host candidates");
+    is(haveRelayProtocol["serverreflexive-undefined"], undefined, "relayProtocol not set for serverreflexive candidates");
+    ok(haveRelayProtocol["relayed-udp"], "Has UDP relay candidate");
+    ok(haveRelayProtocol["relayed-tcp"], "Has TCP relay candidate");
+    // TURN/TLS does not work, see https://bugzilla.mozilla.org/show_bug.cgi?id=1323439
+    // With TURN/TLS working, we should have exactly five entries in haveRelayProtocol.
+    todo(haveRelayProtocol["relayed-tls"], "Has TLS relay candidate. See https://bugzilla.mozilla.org/show_bug.cgi?id=1323439");
+    is(Object.keys(haveRelayProtocol).length, 4, "All candidate types are accounted for");
+  });
+}
+
+runNetworkTest(options => {
+  // uses NAT simulator in order to get srflx candidates.
+  SpecialPowers.pushPrefEnv(
+    {
+      'set': [
+        ['media.peerconnection.nat_simulator.filtering_type', 'ENDPOINT_INDEPENDENT'],
+        ['media.peerconnection.nat_simulator.mapping_type', 'ENDPOINT_INDEPENDENT']
+      ]
+    }, function (options) {
+      const test = new PeerConnectionTest(options);
+      makeOffererNonTrickle(test.chain);
+      makeAnswererNonTrickle(test.chain);
+
+      test.chain.removeAfter("PC_LOCAL_WAIT_FOR_MEDIA_FLOW");
+      test.chain.append([PC_LOCAL_TEST_LOCAL_STATS_RELAYCANDIDATE]);
+
+      test.setMediaConstraints([{ audio: true }], [{ audio: true }]);
+      test.run();
+    })
+}, { useIceServer: true });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -223,28 +223,30 @@ struct ParamTraits<mozilla::dom::RTCIceC
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.mCandidateId);
     WriteParam(aMsg, aParam.mCandidateType);
     WriteParam(aMsg, aParam.mComponentId);
     WriteParam(aMsg, aParam.mIpAddress);
     WriteParam(aMsg, aParam.mMozLocalTransport);
+    WriteParam(aMsg, aParam.mRelayProtocol);
     WriteParam(aMsg, aParam.mPortNumber);
     WriteParam(aMsg, aParam.mTransport);
     WriteRTCStats(aMsg, aParam);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mCandidateId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCandidateType)) ||
         !ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIpAddress)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMozLocalTransport)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mRelayProtocol)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPortNumber)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTransport)) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
     }
 
     return true;
  }
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -150,17 +150,18 @@ enum RTCStatsIceCandidateType {
   "relayed"
 };
 
 dictionary RTCIceCandidateStats : RTCStats {
   DOMString componentId;
   DOMString candidateId;
   DOMString ipAddress;
   DOMString transport;
-  DOMString mozLocalTransport; // needs standardization
+  DOMString mozLocalTransport; // obsoleted by relayProtocol
+  DOMString relayProtocol;
   long portNumber;
   RTCStatsIceCandidateType candidateType;
 };
 
 dictionary RTCCodecStats : RTCStats {
   unsigned long payloadType;       // As used in RTP encoding.
   DOMString codec;                 // video/vp8 or equivalent
   unsigned long clockRate;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -1151,16 +1151,20 @@ static void ToRTCIceCandidateStats(
     cand.mIpAddress.Construct(
         NS_ConvertASCIItoUTF16(candidate.cand_addr.host.c_str()));
     cand.mPortNumber.Construct(candidate.cand_addr.port);
     cand.mTransport.Construct(
         NS_ConvertASCIItoUTF16(candidate.cand_addr.transport.c_str()));
     if (candidateType == RTCStatsType::Local_candidate) {
       cand.mMozLocalTransport.Construct(
           NS_ConvertASCIItoUTF16(candidate.local_addr.transport.c_str()));
+      if (RTCStatsIceCandidateType(candidate.type) == RTCStatsIceCandidateType::Relayed) {
+        cand.mRelayProtocol.Construct(
+            NS_ConvertASCIItoUTF16(candidate.local_addr.transport.c_str()));
+      }
     }
     report->mIceCandidateStats.Value().AppendElement(cand, fallible);
     if (candidate.trickled) {
       report->mTrickledIceCandidateStats.Value().AppendElement(cand, fallible);
     }
   }
 }
 
--- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
+++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
@@ -975,19 +975,19 @@ static uint32_t GetCandidateIpAndTranspo
     CANDIDATE_BITMASK_UDP = 1,
     CANDIDATE_BITMASK_TCP = 1 << 1,
     CANDIDATE_BITMASK_IPV6 = 1 << 2,
   };
 
   uint32_t res = 0;
 
   nsAutoCString transport;
-  // prefer local transport for local relay candidates
-  if (cand->mMozLocalTransport.WasPassed()) {
-    transport.Assign(NS_ConvertUTF16toUTF8(cand->mMozLocalTransport.Value()));
+  // prefer relay transport for local relay candidates
+  if (cand->mRelayProtocol.WasPassed()) {
+    transport.Assign(NS_ConvertUTF16toUTF8(cand->mRelayProtocol.Value()));
   } else {
     transport.Assign(NS_ConvertUTF16toUTF8(cand->mTransport.Value()));
   }
   if (transport == kNrIceTransportUdp) {
     res |= CANDIDATE_BITMASK_UDP;
   } else if (transport == kNrIceTransportTcp) {
     res |= CANDIDATE_BITMASK_TCP;
   }
--- a/toolkit/content/aboutwebrtc/aboutWebrtc.js
+++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js
@@ -845,17 +845,17 @@ ICEStats.prototype = {
   candidateToString(c) {
     if (!c) {
       return "*";
     }
 
     var type = c.candidateType;
 
     if (c.type == "local-candidate" && c.candidateType == "relayed") {
-      type = `${c.candidateType}-${c.mozLocalTransport}`;
+      type = `${c.candidateType}-${c.relayProtocol}`;
     }
 
     return `${c.ipAddress}:${c.portNumber}/${c.transport}(${type})`;
   },
 };
 
 function FoldableSection(parentElement, options = {}) {
   this._foldableElement = document.createElement("div");