Bug 1324788 - Bug 1324688 - Bring RTCIceCandidateStats up to spec r=mjf,jib,smaug
authorNico Grunbaum <na-g@nostrum.com>
Wed, 28 Nov 2018 20:30:07 +0000
changeset 507814 e5c59d7e5a55cd3a312c7915072f57922cefeb1e
parent 507813 d1415db52fe837241d2d7bcc1cf242159806d837
child 507815 95c294286e66c5e4d3ae15706247ad95357b34fd
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmjf, jib, smaug
bugs1324788, 1324688
milestone65.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 1324788 - Bug 1324688 - Bring RTCIceCandidateStats up to spec r=mjf,jib,smaug Bug 1324788 - P1 - rename RTCIceCandidate stat "portNumber" to spec "port" Bug 1324788 - P2 - update RTCIceCandidateStats candidateType enum to spec Bug 1324788 - P3 - add RTCIceCandidatePair.priority stat Bug 1324788 - P4 - update WebRTC ICE candidate stats field componentId to spec name transportId Bug 1324788 - P5 - remove deprecated RTCIceCandidateStats.mozLocalTransport field Bug 1324788 - P6 - update WebRTC ICE candidate stats field transport to spec name, protocol Bug 1324788 - P7 - remove deprecated RTCIceCandidateStats.candidateId Bug 1324788 - P8 - reorder RTCIceCandidateStats dictionary members to match the spec Bug 1324788 - P9 - make RTCIceCandidateStats.transportId ChromeOnly Differential Revision: https://phabricator.services.mozilla.com/D12953
dom/media/PeerConnection.js
dom/media/tests/mochitest/pc.js
dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelay.html
dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTCP.html
dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html
dom/media/tests/mochitest/test_peerConnection_basicAudioNATSrflx.html
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/mtransport/nricemediastream.cpp
media/mtransport/nricemediastream.h
media/webrtc/signaling/src/peerconnection/MediaTransportHandler.cpp
media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
toolkit/content/aboutwebrtc/aboutWebrtc.js
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -304,19 +304,21 @@ class RTCStatsReport {
   // Must be called after our webidl sandwich is made.
 
   makeStatsPublic(warnNullable, warnRemoteNullable, isLegacy) {
     let legacyProps = {};
     for (let key in this._report) {
       const underlying = this._report[key];
       // Add legacy names for renamed stats
       if (underlying.type == "local-candidate" || underlying.type == "remote-candidate") {
-            // Copy stat.address to the legacy field name
-            underlying.ipAddress = underlying.address;
+            // RTCIceCandidateStats transportId is ChromeOnly, don't copy it
+            delete underlying.transportId;
             if (isLegacy) {
+              // Copy stat.address to the legacy field name
+              underlying.ipAddress = underlying.address;
               // Callback stats are frozen to have legacy names
               delete underlying.address;
             }
       }
 
       let internal = Cu.cloneInto(this._report[key], this._win);
       if (isLegacy) {
         internal.type = this._specToLegacyFieldMapping[internal.type] || internal.type;
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1951,25 +1951,25 @@ PeerConnectionWrapper.prototype = {
          "failed to find candidatepair IDs or stats for local: "+ lId +" remote: "+ rId);
       return;
     }
 
     info("checkStatsIceConnectionType verifying: local=" +
          JSON.stringify(lCand) + " remote=" + JSON.stringify(rCand));
     expectedLocalCandidateType = expectedLocalCandidateType || "host";
     var candidateType = lCand.candidateType;
-    if ((lCand.mozLocalTransport === "tcp") && (candidateType === "relayed")) {
-      candidateType = "relayed-tcp";
+    if ((lCand.relayProtocol === "tcp") && (candidateType === "relay")) {
+      candidateType = "relay-tcp";
     }
 
-    if ((expectedLocalCandidateType === "serverreflexive") &&
-        (candidateType === "peerreflexive")) {
+    if ((expectedLocalCandidateType === "srflx") &&
+        (candidateType === "prflx")) {
       // Be forgiving of prflx when expecting srflx, since that can happen due
       // to timing.
-      candidateType = "serverreflexive";
+      candidateType = "srflx";
     }
 
     is(candidateType,
        expectedLocalCandidateType,
        "Local candidate type is what we expected for selected pair");
   },
 
   /**
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelay.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelay.html
@@ -17,18 +17,18 @@
     SpecialPowers.pushPrefEnv(
       {
         'set': [
           ['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'],
           ['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT']
         ]
       }, function (options) {
         options = options || {};
-        options.expectedLocalCandidateType = "serverreflexive";
-        options.expectedRemoteCandidateType = "relayed";
+        options.expectedLocalCandidateType = "srflx";
+        options.expectedRemoteCandidateType = "relay";
         // If both have TURN, it is a toss-up which one will end up using a
         // relay.
         options.turn_disabled_local = true;
         test = new PeerConnectionTest(options);
         // Make sure we don't end up choosing the wrong thing due to delays in
         // trickle. Once we are willing to accept trickle after ICE success, we
         // can maybe wait a bit to allow things to stabilize.
         // TODO(bug 1238249)
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTCP.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTCP.html
@@ -17,18 +17,18 @@
       {
         'set': [
           ['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'],
           ['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT'],
           ['media.peerconnection.nat_simulator.block_udp', true]
         ]
       }, function (options) {
         options = options || {};
-        options.expectedLocalCandidateType = "relayed-tcp";
-        options.expectedRemoteCandidateType = "relayed-tcp";
+        options.expectedLocalCandidateType = "relay-tcp";
+        options.expectedRemoteCandidateType = "relay-tcp";
         // No reason to wait for gathering to complete like the other NAT tests,
         // since relayed-tcp is the only thing that can work.
         test = new PeerConnectionTest(options);
         test.setMediaConstraints([{audio: true}], [{audio: true}]);
         test.run();
       })
   }, { useIceServer: true });
 </script>
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATRelayTLS.html
@@ -18,18 +18,18 @@
         'set': [
           ['media.peerconnection.nat_simulator.filtering_type', 'PORT_DEPENDENT'],
           ['media.peerconnection.nat_simulator.mapping_type', 'PORT_DEPENDENT'],
           ['media.peerconnection.nat_simulator.block_udp', true],
           ['media.peerconnection.nat_simulator.block_tcp', true]
         ]
       }, function (options) {
         options = options || {};
-        options.expectedLocalCandidateType = "relayed-tcp";
-        options.expectedRemoteCandidateType = "relayed-tcp";
+        options.expectedLocalCandidateType = "relay-tcp";
+        options.expectedRemoteCandidateType = "relay-tcp";
         // No reason to wait for gathering to complete like the other NAT tests,
         // since relayed-tcp is the only thing that can work.
         test = new PeerConnectionTest(options);
         test.setMediaConstraints([{audio: true}], [{audio: true}]);
         test.run();
       })
   }, { useIceServer: true });
 </script>
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioNATSrflx.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioNATSrflx.html
@@ -17,18 +17,18 @@
     SpecialPowers.pushPrefEnv(
       {
         'set': [
           ['media.peerconnection.nat_simulator.filtering_type', 'ENDPOINT_INDEPENDENT'],
           ['media.peerconnection.nat_simulator.mapping_type', 'ENDPOINT_INDEPENDENT']
         ]
       }, function (options) {
         options = options || {};
-        options.expectedLocalCandidateType = "serverreflexive";
-        options.expectedRemoteCandidateType = "serverreflexive";
+        options.expectedLocalCandidateType = "srflx";
+        options.expectedRemoteCandidateType = "srflx";
         test = new PeerConnectionTest(options);
         // Make sure we don't end up choosing the wrong thing due to delays in
         // trickle. Once we are willing to accept trickle after ICE success, we
         // can maybe wait a bit to allow things to stabilize.
         // TODO(bug 1238249)
         makeOffererNonTrickle(test.chain);
         makeAnswererNonTrickle(test.chain);
         test.setMediaConstraints([{audio: true}], [{audio: true}]);
--- a/dom/media/tests/mochitest/test_peerConnection_stats.html
+++ b/dom/media/tests/mochitest/test_peerConnection_stats.html
@@ -52,31 +52,30 @@ var statsExpectedByType = {
     unimplemented: ["totalRoundTripTime", "currentRoundTripTime",
       "availableOutgoingBitrate", "availableIncomingBitrate",
       "requestsReceived", "requestsSent", "responsesReceived",
       "responsesSent", "retransmissionsReceived", "retransmissionsSent",
       "consentRequestsSent",],
     deprecated: [],
   },
   "local-candidate": {
-    expected: ["id", "timestamp", "type", "componentId", "address",
-               "ipAddress", "transport", "mozLocalTransport", "portNumber",
-               "candidateType"],
-    optional: [],
-    unimplemented: ["port", "networkType", "protocol", "relayProtocol",
-                    "priority", "url"],
-    deprecated: ["candidateId"],
+    expected: ["id", "timestamp", "type", "address",
+               "protocol", "port", "candidateType", "priority"],
+    optional: ["relayProtocol"],
+    unimplemented: ["networkType", "url", "transportId"],
+    deprecated: ["candidateId", "portNumber", "ipAddress", "componentId", "mozLocalTransport",
+      "transport"],
   },
   "remote-candidate": {
-    expected: ["id", "timestamp", "type", "componentId", "address",
-               "ipAddress", "transport", "portNumber", "candidateType"],
-    optional: [],
-    unimplemented: ["port", "networkType", "protocol", "relayProtocol",
-                    "priority", "url"],
-    deprecated: ["candidateId"],
+    expected: ["id", "timestamp", "type", "address",
+               "protocol", "port", "candidateType", "priority"],
+    optional: ["relayProtocol"],
+    unimplemented: ["networkType", "url", "transportId"],
+    deprecated: ["candidateId", "portNumber", "ipAddress", "componentId", "mozLocalTransport",
+                 "transport"],
   },
   "certificate": { skip: true },
 };
 ["in", "out"].forEach(pre => {
   let s = statsExpectedByType[pre + "bound-rtp"];
   s.optional = [...s.optional, ...s.localVideoOnly];
 });
 
@@ -496,37 +495,43 @@ var pedanticChecks = report => {
           !stat.selected),
         stat.type + ".selected is undefined, true when state is succeeded, "
         + "or false. value="
         + stat.selected);
 
     } else if (stat.type == "local-candidate" || stat.type == "remote-candidate") {
       info(`candidate is ${JSON.stringify(stat)}`);
 
-      // componentId
-      ok(stat.componentId, `${stat.type} has componentId. value=${stat.componentId}`);
-
-      // ipAddress
-      ok(stat.ipAddress, `${stat.type} has ipAddress. value=${stat.ipAddress}`);
-
-      // transport
-      ok(stat.transport, `${stat.type} has transport. value=${stat.transport}`);
+      // address
+      ok(stat.address, `${stat.type} has address. value=${stat.address}`);
 
-      if (stat.type == "local-candidate") {
-        // mozLocalTransport
-        ok(stat.mozLocalTransport, `${stat.type} has mozLocalTransport. value=${stat.mozLocalTransport}`);
-      }
+      // protocol
+      ok(stat.protocol, `${stat.type} has protocol. value=${stat.protocol}`);
 
-      // portNumber
-      ok(stat.portNumber >= 0, `${stat.type} has portNumber >= 0. value=${stat.portNumber}`);
-      ok(stat.portNumber <= 65535, `${stat.type} has portNumber <= 65535. value=${stat.portNumber}`);
+      // port
+      ok(stat.port >= 0, `${stat.type} has port >= 0. value=${stat.port}`);
+      ok(stat.port <= 65535, `${stat.type} has port <= 65535. value=${stat.port}`);
 
       // candidateType
       ok(stat.candidateType, `${stat.type} has candidateType. value=${stat.candidateType}`);
 
+      // priority
+      ok(stat.priority > 0 && stat.priority < (2**32 - 1),
+         `${stat.type} has priority between 1 and 2^32 - 1 inc. ` +
+         `value=${stat.priority}`);
+
+      // relayProtocol
+      if (stat.type == "local-candidate" && stat.candidateType == "relay") {
+        ok(stat.relayProtocol,
+          `relay ${stat.type} has relayProtocol. value=${stat.relayProtocol}`);
+      } else {
+        is(stat.relayProtocol, undefined,
+          `relayProtocol is undefined for candidates that are not relay and ` +
+          `local. value=${stat.relayProtocol}`);
+      }
     }
 
     //
     // Ensure everything was tested
     //
     [...expectations.expected, ...expectations.optional].forEach(field => {
       ok(Object.keys(tested).includes(field), stat.type + "." + field
         + " was tested.");
--- a/dom/media/tests/mochitest/test_peerConnection_stats_relayProtocol.html
+++ b/dom/media/tests/mochitest/test_peerConnection_stats_relayProtocol.html
@@ -15,22 +15,22 @@ var PC_LOCAL_TEST_LOCAL_STATS_RELAYCANDI
   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");
+    is(haveRelayProtocol["srvflx-undefined"], undefined, "relayProtocol not set for server reflexive candidates");
+    ok(haveRelayProtocol["relay-udp"], "Has UDP relay candidate");
+    ok(haveRelayProtocol["relay-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");
+    todo(haveRelayProtocol["relay-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(
     {
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -39,21 +39,21 @@ struct ParamTraits<mozilla::dom::RTCStat
 template <>
 struct ParamTraits<mozilla::dom::RTCStatsIceCandidatePairState>
     : public ContiguousEnumSerializer<
           mozilla::dom::RTCStatsIceCandidatePairState,
           mozilla::dom::RTCStatsIceCandidatePairState::Frozen,
           mozilla::dom::RTCStatsIceCandidatePairState::EndGuard_> {};
 
 template <>
-struct ParamTraits<mozilla::dom::RTCStatsIceCandidateType>
+struct ParamTraits<mozilla::dom::RTCIceCandidateType>
     : public ContiguousEnumSerializer<
-          mozilla::dom::RTCStatsIceCandidateType,
-          mozilla::dom::RTCStatsIceCandidateType::Host,
-          mozilla::dom::RTCStatsIceCandidateType::EndGuard_> {};
+          mozilla::dom::RTCIceCandidateType,
+          mozilla::dom::RTCIceCandidateType::Host,
+          mozilla::dom::RTCIceCandidateType::EndGuard_> {};
 
 template <>
 struct ParamTraits<mozilla::dom::RTCStatsReportInternal> {
   typedef mozilla::dom::RTCStatsReportInternal paramType;
 
   static void Write(Message* aMsg, const paramType& aParam) {
     WriteParam(aMsg, aParam.mClosed);
     WriteParam(aMsg, aParam.mCodecStats);
@@ -203,37 +203,35 @@ struct ParamTraits<mozilla::dom::RTCIceC
   }
 };
 
 template <>
 struct ParamTraits<mozilla::dom::RTCIceCandidateStats> {
   typedef mozilla::dom::RTCIceCandidateStats paramType;
 
   static void Write(Message* aMsg, const paramType& aParam) {
-    WriteParam(aMsg, aParam.mCandidateId);
     WriteParam(aMsg, aParam.mCandidateType);
-    WriteParam(aMsg, aParam.mComponentId);
+    WriteParam(aMsg, aParam.mPriority);
+    WriteParam(aMsg, aParam.mTransportId);
     WriteParam(aMsg, aParam.mAddress);
-    WriteParam(aMsg, aParam.mMozLocalTransport);
     WriteParam(aMsg, aParam.mRelayProtocol);
-    WriteParam(aMsg, aParam.mPortNumber);
-    WriteParam(aMsg, aParam.mTransport);
+    WriteParam(aMsg, aParam.mPort);
+    WriteParam(aMsg, aParam.mProtocol);
     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)) ||
+    if (!ReadParam(aMsg, aIter, &(aResult->mCandidateType)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mPriority)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mTransportId)) ||
         !ReadParam(aMsg, aIter, &(aResult->mAddress)) ||
-        !ReadParam(aMsg, aIter, &(aResult->mMozLocalTransport)) ||
         !ReadParam(aMsg, aIter, &(aResult->mRelayProtocol)) ||
-        !ReadParam(aMsg, aIter, &(aResult->mPortNumber)) ||
-        !ReadParam(aMsg, aIter, &(aResult->mTransport)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mPort)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mProtocol)) ||
         !ReadRTCStats(aMsg, aIter, aResult)) {
       return false;
     }
 
     return true;
   }
 };
 
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -138,32 +138,34 @@ dictionary RTCIceCandidatePairStats : RT
   unsigned long long bytesReceived;
   DOMHighResTimeStamp lastPacketSentTimestamp;
   DOMHighResTimeStamp lastPacketReceivedTimestamp;
   boolean selected;
   [ChromeOnly]
   unsigned long componentId; // moz
 };
 
-enum RTCStatsIceCandidateType {
+enum RTCIceCandidateType {
   "host",
-  "serverreflexive",
-  "peerreflexive",
-  "relayed"
+  "srflx",
+  "prflx",
+  "relay"
 };
 
 dictionary RTCIceCandidateStats : RTCStats {
-  DOMString componentId;
-  DOMString candidateId;
   DOMString address;
-  DOMString transport;
-  DOMString mozLocalTransport; // obsoleted by relayProtocol
+  long port;
+  DOMString protocol;
+  RTCIceCandidateType candidateType;
+  long priority;
   DOMString relayProtocol;
-  long portNumber;
-  RTCStatsIceCandidateType candidateType;
+  // Because we use this internally but don't support RTCIceCandidateStats,
+  // we need to keep the field as ChromeOnly. Bug 1225723
+  [ChromeOnly]
+  DOMString transportId;
 };
 
 dictionary RTCCodecStats : RTCStats {
   unsigned long payloadType;       // As used in RTP encoding.
   DOMString codec;                 // video/vp8 or equivalent
   unsigned long clockRate;
   unsigned long channels;          // 2=stereo, missing for most other cases.
   DOMString parameters;            // From SDP description line
--- a/media/mtransport/nricemediastream.cpp
+++ b/media/mtransport/nricemediastream.cpp
@@ -164,16 +164,17 @@ static bool ToNrIceCandidate(const nr_ic
       break;
   }
 
   out->type = type;
   out->tcp_type = tcp_type;
   out->codeword = candc.codeword;
   out->label = candc.label;
   out->trickled = candc.trickled;
+  out->priority = candc.priority;
   return true;
 }
 
 // Make an NrIceCandidate from the candidate |cand|.
 // This is not a member fxn because we want to hide the
 // defn of nr_ice_candidate but we pass by reference.
 static UniquePtr<NrIceCandidate> MakeNrIceCandidate(const nr_ice_candidate& candc) {
   UniquePtr<NrIceCandidate> out(new NrIceCandidate());
--- a/media/mtransport/nricemediastream.h
+++ b/media/mtransport/nricemediastream.h
@@ -91,16 +91,17 @@ struct NrIceCandidate {
 
   NrIceAddr cand_addr;
   NrIceAddr local_addr;
   Type type;
   TcpType tcp_type;
   std::string codeword;
   std::string label;
   bool trickled;
+  uint32_t priority;
 };
 
 struct NrIceCandidatePair {
 
   enum State {
     STATE_FROZEN,
     STATE_WAITING,
     STATE_IN_PROGRESS,
--- a/media/webrtc/signaling/src/peerconnection/MediaTransportHandler.cpp
+++ b/media/webrtc/signaling/src/peerconnection/MediaTransportHandler.cpp
@@ -597,43 +597,41 @@ MediaTransportHandler::ExitPrivateMode()
   if (log) {
     log->ExitPrivateMode();
   }
 }
 
 static void ToRTCIceCandidateStats(
     const std::vector<NrIceCandidate>& candidates,
     dom::RTCStatsType candidateType,
-    const nsString& componentId,
+    const nsString& transportId,
     DOMHighResTimeStamp now,
     dom::RTCStatsReportInternal* report) {
 
   MOZ_ASSERT(report);
   for (const auto& candidate : candidates) {
     dom::RTCIceCandidateStats cand;
     cand.mType.Construct(candidateType);
     NS_ConvertASCIItoUTF16 codeword(candidate.codeword.c_str());
-    cand.mComponentId.Construct(componentId);
+    cand.mTransportId.Construct(transportId);
     cand.mId.Construct(codeword);
     cand.mTimestamp.Construct(now);
     cand.mCandidateType.Construct(
-        dom::RTCStatsIceCandidateType(candidate.type));
+        dom::RTCIceCandidateType(candidate.type));
+    cand.mPriority.Construct(candidate.priority);
     cand.mAddress.Construct(
         NS_ConvertASCIItoUTF16(candidate.cand_addr.host.c_str()));
-    cand.mPortNumber.Construct(candidate.cand_addr.port);
-    cand.mTransport.Construct(
+    cand.mPort.Construct(candidate.cand_addr.port);
+    cand.mProtocol.Construct(
         NS_ConvertASCIItoUTF16(candidate.cand_addr.transport.c_str()));
-    if (candidateType == dom::RTCStatsType::Local_candidate) {
-      cand.mMozLocalTransport.Construct(
+    if (candidateType == dom::RTCStatsType::Local_candidate &&
+        dom::RTCIceCandidateType(candidate.type) ==
+            dom::RTCIceCandidateType::Relay) {
+      cand.mRelayProtocol.Construct(
           NS_ConvertASCIItoUTF16(candidate.local_addr.transport.c_str()));
-      if (dom::RTCStatsIceCandidateType(candidate.type) ==
-            dom::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
@@ -888,17 +888,17 @@ static uint32_t GetCandidateIpAndTranspo
 
   uint32_t res = 0;
 
   nsAutoCString transport;
   // 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()));
+    transport.Assign(NS_ConvertUTF16toUTF8(cand->mProtocol.Value()));
   }
   if (transport == kNrIceTransportUdp) {
     res |= CANDIDATE_BITMASK_UDP;
   } else if (transport == kNrIceTransportTcp) {
     res |= CANDIDATE_BITMASK_TCP;
   }
 
   if (cand->mAddress.Value().FindChar(':') != -1) {
@@ -953,19 +953,19 @@ static void StoreLongTermICEStatisticsIm
   for (size_t i = 0;
        i < query->report->mIceCandidateStats.Value().Length();
        ++i) {
     const RTCIceCandidateStats &cand =
       query->report->mIceCandidateStats.Value()[i];
 
     if (!cand.mType.WasPassed() ||
         !cand.mCandidateType.WasPassed() ||
-        !cand.mTransport.WasPassed() ||
+        !cand.mProtocol.WasPassed() ||
         !cand.mAddress.WasPassed() ||
-        !cand.mComponentId.WasPassed()) {
+        !cand.mTransportId.WasPassed()) {
       // Crash on debug, ignore this candidate otherwise.
       MOZ_CRASH();
       continue;
     }
 
     /* The bitmask after examaning a candidate should look like this:
      * REMOTE_GATHERED_HOST_UDP = 1,
      * REMOTE_GATHERED_HOST_TCP = 1 << 1,
@@ -1001,29 +1001,29 @@ static void StoreLongTermICEStatisticsIm
 
     uint32_t candBitmask = GetCandidateIpAndTransportMask(&cand);
 
     // Note: shift values need to result in the above enum table
     if (cand.mType.Value() == RTCStatsType::Local_candidate) {
       candBitmask <<= kLocalShift;
     }
 
-    if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Serverreflexive) {
+    if (cand.mCandidateType.Value() == RTCIceCandidateType::Srflx) {
       candBitmask <<= kSrflxShift;
-    } else if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Relayed) {
+    } else if (cand.mCandidateType.Value() == RTCIceCandidateType::Relay) {
       candBitmask <<= kRelayShift;
-    } else if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Peerreflexive) {
+    } else if (cand.mCandidateType.Value() == RTCIceCandidateType::Prflx) {
       candBitmask <<= kPrflxShift;
     }
 
-    // Note: this is not a "component" in the ICE definition, this is really a
-    // stream ID. This is just the way the stats API is standardized right now.
+    // Note: this is not a "transport", this is really a stream ID. This is just
+    // the way the stats API is standardized right now.
     // Very confusing.
     std::string streamId(
-      NS_ConvertUTF16toUTF8(cand.mComponentId.Value()).get());
+      NS_ConvertUTF16toUTF8(cand.mTransportId.Value()).get());
 
     streamResults[streamId].candidateTypeBitpattern |= candBitmask;
   }
 
   for (auto& streamResult : streamResults) {
     Telemetry::RecordWebrtcIceCandidates(streamResult.second.candidateTypeBitpattern,
                                          streamResult.second.streamSucceeded);
   }
--- a/toolkit/content/aboutwebrtc/aboutWebrtc.js
+++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js
@@ -848,17 +848,17 @@ ICEStats.prototype = {
     }
 
     var type = c.candidateType;
 
     if (c.type == "local-candidate" && c.candidateType == "relayed") {
       type = `${c.candidateType}-${c.relayProtocol}`;
     }
 
-    return `${c.address}:${c.portNumber}/${c.transport}(${type})`;
+    return `${c.address}:${c.port}/${c.transport}(${type})`;
   },
 };
 
 function FoldableSection(parentElement, options = {}) {
   this._foldableElement = document.createElement("div");
   if (parentElement) {
     let sectionCtrl = renderElement("div", null, {
       className: "section-ctrl no-print",