Bug 1321628 - add ice restart and rollback counts to about:webrtc. r=drno, r=smaug draft
authorMichael Froman <mfroman@mozilla.com>
Wed, 23 Nov 2016 11:48:04 -0600
changeset 448380 d7ee5a85927ea6fc698ac85b840b224e30eddd4d
parent 446527 3853c539a1b7c803f1075d2c3ecefbdd314af1d8
child 539293 b606c6a3b54789f0f810e1a189e8510790c9d113
push id38346
push userbmo:mfroman@nostrum.com
push dateSat, 10 Dec 2016 03:00:13 +0000
reviewersdrno, smaug
bugs1321628
milestone53.0a1
Bug 1321628 - add ice restart and rollback counts to about:webrtc. r=drno, r=smaug MozReview-Commit-ID: FmZMtwzvmhX
dom/media/webrtc/WebrtcGlobal.h
dom/webidl/RTCStatsReport.webidl
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
toolkit/content/aboutwebrtc/aboutWebrtc.js
toolkit/locales/en-US/chrome/global/aboutWebrtc.properties
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -107,16 +107,18 @@ struct ParamTraits<mozilla::dom::RTCStat
     WriteParam(aMsg, aParam.mInboundRTPStreamStats);
     WriteParam(aMsg, aParam.mLocalSdp);
     WriteParam(aMsg, aParam.mMediaStreamStats);
     WriteParam(aMsg, aParam.mMediaStreamTrackStats);
     WriteParam(aMsg, aParam.mOutboundRTPStreamStats);
     WriteParam(aMsg, aParam.mPcid);
     WriteParam(aMsg, aParam.mRemoteSdp);
     WriteParam(aMsg, aParam.mTimestamp);
+    WriteParam(aMsg, aParam.mIceRestarts);
+    WriteParam(aMsg, aParam.mIceRollbacks);
     WriteParam(aMsg, aParam.mTransportStats);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
   {
     if (!ReadParam(aMsg, aIter, &(aResult->mClosed)) ||
         !ReadParam(aMsg, aIter, &(aResult->mCodecStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mIceCandidatePairStats)) ||
@@ -125,16 +127,18 @@ struct ParamTraits<mozilla::dom::RTCStat
         !ReadParam(aMsg, aIter, &(aResult->mInboundRTPStreamStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mLocalSdp)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMediaStreamStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mMediaStreamTrackStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mOutboundRTPStreamStats)) ||
         !ReadParam(aMsg, aIter, &(aResult->mPcid)) ||
         !ReadParam(aMsg, aIter, &(aResult->mRemoteSdp)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTimestamp)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mIceRestarts)) ||
+        !ReadParam(aMsg, aIter, &(aResult->mIceRollbacks)) ||
         !ReadParam(aMsg, aIter, &(aResult->mTransportStats))) {
       return false;
     }
 
     return true;
   }
 };
 
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -158,16 +158,18 @@ dictionary RTCStatsReportInternal {
   sequence<RTCTransportStats>         transportStats;
   sequence<RTCIceComponentStats>      iceComponentStats;
   sequence<RTCIceCandidatePairStats>  iceCandidatePairStats;
   sequence<RTCIceCandidateStats>      iceCandidateStats;
   sequence<RTCCodecStats>             codecStats;
   DOMString                           localSdp;
   DOMString                           remoteSdp;
   DOMHighResTimeStamp                 timestamp;
+  unsigned long                       iceRestarts;
+  unsigned long                       iceRollbacks;
   boolean                             closed; // Is the PC now closed
 };
 
 [Pref="media.peerconnection.enabled",
 // TODO: Use MapClass here once it's available (Bug 928114)
 // MapClass(DOMString, object)
  JSImplementation="@mozilla.org/dom/rtcstatsreport;1"]
 interface RTCStatsReport {
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -331,16 +331,18 @@ PeerConnectionImpl::PeerConnectionImpl(c
   , mIdentity(nullptr)
 #endif
   , mPrivacyRequested(false)
   , mSTSThread(nullptr)
   , mAllowIceLoopback(false)
   , mAllowIceLinkLocal(false)
   , mMedia(nullptr)
   , mUuidGen(MakeUnique<PCUuidGenerator>())
+  , mIceRestartCount(0)
+  , mIceRollbackCount(0)
   , mNumAudioStreams(0)
   , mNumVideoStreams(0)
   , mHaveConfiguredCodecs(false)
   , mHaveDataStream(false)
   , mAddCandidateErrorCount(0)
   , mTrickle(true) // TODO(ekr@rtfm.com): Use pref
   , mNegotiationNeeded(false)
   , mPrivateWindow(false)
@@ -1732,27 +1734,29 @@ PeerConnectionImpl::RollbackIceRestart()
   if (NS_FAILED(nrv)) {
     CSFLogError(logTag, "%s: Couldn't set ICE credentials, res=%u",
                          __FUNCTION__,
                          static_cast<unsigned>(nrv));
     return nrv;
   }
   mPreviousIceUfrag = "";
   mPreviousIcePwd = "";
+  ++mIceRollbackCount;
 
   return NS_OK;
 }
 
 void
 PeerConnectionImpl::FinalizeIceRestart()
 {
   mMedia->FinalizeIceRestart();
   // clear the previous ice creds since they are no longer needed
   mPreviousIceUfrag = "";
   mPreviousIcePwd = "";
+  ++mIceRestartCount;
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
 {
   PC_AUTO_ENTER_API_CALL(true);
 
   if (!aSDP) {
@@ -3603,16 +3607,18 @@ PeerConnectionImpl::BuildStatsQuery_m(
 
   // We do not use the pcHandle here, since that's risky to expose to content.
   query->report = new RTCStatsReportInternalConstruct(
       NS_ConvertASCIItoUTF16(mName.c_str()),
       query->now);
 
   query->iceStartTime = mIceStartTime;
   query->failed = isFailed(mIceConnectionState);
+  query->report->mIceRestarts.Construct(mIceRestartCount);
+  query->report->mIceRollbacks.Construct(mIceRollbackCount);
 
   // Populate SDP on main
   if (query->internalStats) {
     if (mJsepSession) {
       std::string localDescription = mJsepSession->GetLocalDescription();
       std::string remoteDescription = mJsepSession->GetRemoteDescription();
       query->report->mLocalSdp.Construct(
           NS_ConvertASCIItoUTF16(localDescription.c_str()));
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -813,16 +813,18 @@ private:
   bool mAllowIceLinkLocal;
   RefPtr<PeerConnectionMedia> mMedia;
 
   // The JSEP negotiation session.
   mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
   mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
   std::string mPreviousIceUfrag; // used during rollback of ice restart
   std::string mPreviousIcePwd; // used during rollback of ice restart
+  unsigned long mIceRestartCount;
+  unsigned long mIceRollbackCount;
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
   // Start time of ICE, used for telemetry
   mozilla::TimeStamp mIceStartTime;
   // Start time of call used for Telemetry
   mozilla::TimeStamp mStartTime;
 #endif
 
--- a/toolkit/content/aboutwebrtc/aboutWebrtc.js
+++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js
@@ -673,21 +673,41 @@ ICEStats.prototype = {
        getString("priority"), getString("nominated"), getString("selected")],
       tbody);
 
     let div = document.createElement("div");
     let heading = document.createElement("h4");
 
     heading.textContent = getString("ice_stats_heading");
     div.appendChild(heading);
+
     div.appendChild(statsTable.render());
+    div.appendChild(this.renderIceMetric("ice_restart_count_label",
+                                         this._report.iceRestarts));
+    div.appendChild(this.renderIceMetric("ice_rollback_count_label",
+                                         this._report.iceRollbacks));
 
     return div;
   },
 
+  renderIceMetric: function(labelName, value) {
+    let info = document.createElement("div");
+    let label = document.createElement("span");
+    let body = document.createElement("span");
+
+    label.className = "info-label";
+    label.textContent = `${getString(labelName)}: `;
+    info.appendChild(label);
+
+    body.className = "info-body";
+    body.textContent = value;
+    info.appendChild(body);
+    return info;
+  },
+
   generateICEStats: function() {
     // Create an index based on candidate ID for each element in the
     // iceCandidateStats array.
     let candidates = new Map();
 
     for (let candidate of this._report.iceCandidateStats) {
       candidates.set(candidate.id, candidate);
     }
--- a/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutWebrtc.properties
@@ -55,16 +55,18 @@ remote_sdp_heading = Remote SDP
 rtp_stats_heading = RTP Stats
 
 # LOCALIZATION NOTE (ice_state, ice_stats_heading): "ICE" is an abbreviation
 # for Interactive Connectivity Establishment, which is an IETF protocol,
 # and should not normally be translated. "Stats" is an abbreviation for
 # Statistics.
 ice_state = ICE State
 ice_stats_heading = ICE Stats
+ice_restart_count_label = ICE restarts
+ice_rollback_count_label = ICE rollbacks
 
 # LOCALIZATION NOTE (av_sync_label): "A/V" stands for Audio/Video.
 # "sync" is an abbreviation for sychronization. This is used as
 # a data label.
 av_sync_label = A/V sync
 
 # LOCALIZATION NOTE (jitter_buffer_delay_label): A jitter buffer is an
 # element in the processing chain, see http://wikipedia.org/wiki/Jitter