Bug 1455724 - add telemetry for legacy PeerConnection getStats API usage r=mjf
authorNico Grunbaum
Mon, 23 Apr 2018 09:49:32 -0700
changeset 486098 d94aa8ef3c68ddad3b9a20ec932952865fbe2cf3
parent 486097 52bd814d3589b8b7d6194e456b7fd7068af397e1
child 486099 53626fd5c3bc0e33d38890b38160611b5a3fad04
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmjf
bugs1455724
milestone63.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 1455724 - add telemetry for legacy PeerConnection getStats API usage r=mjf MozReview-Commit-ID: L17M2whvxpV
dom/media/PeerConnection.js
toolkit/components/telemetry/Scalars.yaml
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -35,16 +35,20 @@ const PC_MANAGER_CID = Components.ID("{7
 const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
 const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
 const PC_SENDER_CID = Components.ID("{4fff5d46-d827-4cd4-a970-8fd53977440e}");
 const PC_RECEIVER_CID = Components.ID("{d974b814-8fde-411c-8c45-b86791b81030}");
 const PC_TRANSCEIVER_CID = Components.ID("{09475754-103a-41f5-a2d0-e1f27eb0b537}");
 const PC_COREQUEST_CID = Components.ID("{74b2122d-65a8-4824-aa9e-3d664cb75dc2}");
 const PC_DTMF_SENDER_CID = Components.ID("{3610C242-654E-11E6-8EC0-6D1BE389A607}");
 
+const TELEMETRY_PC_CONNECTED = "webrtc.peerconnection.connected";
+const TELEMETRY_PC_CALLBACK_GETSTATS = "webrtc.peerconnection.legacy_callback_stats_used";
+const TELEMETRY_PC_PROMISE_GETSTATS = "webrtc.peerconnection.promise_stats_used";
+const TELEMETRY_PC_PROMISE_AND_CALLBACK_GETSTATS = "webrtc.peerconnection.promise_and_callback_stats_used";
 function logMsg(msg, file, line, flag, winID) {
   let scriptErrorClass = Cc["@mozilla.org/scripterror;1"];
   let scriptError = scriptErrorClass.createInstance(Ci.nsIScriptError);
   scriptError.initWithWindowID(msg, file, null, line, 0, flag,
                                "content javascript", winID);
   Services.console.logMessage(scriptError);
 }
 
@@ -372,16 +376,42 @@ setupPrototype(RTCStatsReport, {
         "inbound-rtp": "inboundrtp",
         "outbound-rtp": "outboundrtp",
         "candidate-pair": "candidatepair",
         "local-candidate": "localcandidate",
         "remote-candidate": "remotecandidate"
   }
 });
 
+// This is its own class so that it does not need to be exposed to the client.
+class PeerConnectionTelemetry {
+  // Record which style(s) of invocation for getStats are used
+  recordPromiseAndCallbackGetStats(isCallback) {
+    if (!this._hasCallbackStatsBeenUsed && isCallback) {
+      this._hasCallbackStatsBeenUsed = true;
+      Services.telemetry.scalarAdd(TELEMETRY_PC_CALLBACK_GETSTATS, 1);
+    }
+    if (!this._hasPromiseStatsBeenUsed && !isCallback) {
+      this._hasPromiseStatsBeenUsed = true;
+      Services.telemetry.scalarAdd(TELEMETRY_PC_PROMISE_GETSTATS, 1);
+    }
+    if (this._hasCallbackStatsBeenUsed && this._hasPromiseStatsBeenUsed) {
+      Services.telemetry.scalarAdd(
+        TELEMETRY_PC_PROMISE_AND_CALLBACK_GETSTATS, 1);
+      // Everything that can be recorded has been at this point.
+      this.recordPromiseAndCallbackGetStats = () => {};
+    }
+  }
+  // ICE connection state enters connected or completed.
+  recordConnected() {
+    Services.telemetry.scalarAdd(TELEMETRY_PC_CONNECTED, 1);
+    this.recordConnected = () => {};
+  }
+}
+
 // Cache for RTPSourceEntries
 // Note: each cache is only valid for one JS event loop execution
 class RTCRtpSourceCache {
   constructor() {
     // The time in RTP source time (ms)
     this.tsNowInRtpSourceTime = null;
     // The time in JS
     this.jsTimestamp = null;
@@ -418,16 +448,18 @@ class RTCPeerConnection {
     this._iceGatheredRelayCandidates = false;
     // Stored webrtc timing information
     this._storedRtpSourceReferenceTime = null;
     // TODO: Remove legacy API eventually
     // see Bug 1328194
     this._onGetStatsIsLegacy = false;
     // Stores cached RTP sources state
     this._rtpSourceCache = new RTCRtpSourceCache();
+    // Records telemetry
+    this._pcTelemetry = new PeerConnectionTelemetry();
   }
 
   init(win) {
     this._win = win;
   }
 
   __init(rtcConfig) {
     this._winID = this._win.windowUtils.currentInnerWindowID;
@@ -1586,16 +1618,20 @@ class RTCPeerConnection {
       this._iceConnectionState = state;
       _globalPCList.notifyLifecycleObservers(this, "iceconnectionstatechange");
       this.dispatchEvent(new this._win.Event("iceconnectionstatechange"));
     }
   }
 
   getStats(selector, onSucc, onErr) {
     let isLegacy = (typeof onSucc) == "function";
+    if (this._iceConnectionState === "completed" ||
+        this._iceConnectionState === "connected") {
+      this._pcTelemetry.recordPromiseAndCallbackGetStats(isLegacy);
+    }
     if (isLegacy &&
         this._warnDeprecatedStatsCallbacksNullable.warn) {
       this._warnDeprecatedStatsCallbacksNullable.warn();
       this._warnDeprecatedStatsCallbacksNullable.warn = null;
     }
     return this._auto(onSucc, onErr, () => this._getStats(selector, isLegacy));
   }
 
@@ -1791,16 +1827,17 @@ class PeerConnectionObserver {
       } else if (iceConnectionState === "failed") {
         checking_histogram.add(false);
       }
     } else if (pc.iceConnectionState === "checking") {
       var success_histogram = Services.telemetry.getHistogramById("WEBRTC_ICE_SUCCESS_RATE");
       if (iceConnectionState === "completed" ||
           iceConnectionState === "connected") {
         success_histogram.add(true);
+        pc._pcTelemetry.recordConnected();
       } else if (iceConnectionState === "failed") {
         success_histogram.add(false);
       }
     }
 
     if (iceConnectionState === "failed") {
       if (!pc._hasStunServer) {
         pc.logError("ICE failed, add a STUN server and see about:webrtc for more details");
--- a/toolkit/components/telemetry/Scalars.yaml
+++ b/toolkit/components/telemetry/Scalars.yaml
@@ -632,16 +632,89 @@ preferences:
     expires: "62"
     kind: boolean
     notification_emails:
       - yzenevich@mozilla.com
     release_channel_collection: opt-out
     record_in_processes:
       - 'main'
 
+# The following section contains WebRTC JS API scalars
+# For more information on WebRTC, see https://www.w3.org/TR/webrtc/
+# For more info on ICE, see https://tools.ietf.org/html/rfc5245
+webrtc.peerconnection:
+  connected:
+    bug_numbers:
+      - 1455724
+    description: >
+      The number of RTCPeerConnection objects that established connections.
+      This is incremented the first time a RTCPeerConnection object's
+      iceConnectionState becomes "connected" or "complete".
+      For more information on WebRTC, see https://www.w3.org/TR/webrtc/
+    expires: "65"
+    kind: uint
+    notification_emails:
+      - ngrunbaum@mozilla.com
+    release_channel_collection: opt-in
+    record_in_processes:
+      - 'main'
+      - 'content'
+
+  legacy_callback_stats_used:
+    bug_numbers:
+      - 1455724
+    description: >
+      The number of RTCPeerConnections in which the current statistics
+      API is called. Recorded the first time getStats is called using the
+      deprecated callback based API on a RTCPeerConnection that has an
+      iceConnectionState of "complete" or "connected".
+    expires: "65"
+    kind: uint
+    notification_emails:
+      - ngrunbaum@mozilla.com
+    release_channel_collection: opt-in
+    record_in_processes:
+      - 'main'
+      - 'content'
+
+  promise_stats_used:
+    bug_numbers:
+      - 1455724
+    description: >
+      The number of RTCPeerConnection objects in which the current statistics
+      API is called. This is recorded the first time getStats is called using
+      the promise based API on a RTCPeerConnection that has an
+      iceConnectionState of "complete" or "connected".
+    expires: "65"
+    kind: uint
+    notification_emails:
+      - ngrunbaum@mozilla.com
+    release_channel_collection: opt-in
+    record_in_processes:
+      - 'main'
+      - 'content'
+
+  promise_and_callback_stats_used:
+    bug_numbers:
+      - 1455724
+    description: >
+      The number of RTCPeerConnection objects in which both the legacy callback
+      statistics API and the modern promise statistics API are used. This is
+      recorded once for each RTCPeerConnection after the callback and promise
+      getStats API has been called on a RTCPeerConnection that has an
+      iceConnectionState of "complete" or "connected".
+    expires: "65"
+    kind: uint
+    notification_emails:
+      - ngrunbaum@mozilla.com
+    release_channel_collection: opt-in
+    record_in_processes:
+      - 'main'
+      - 'content'
+
 # The following section contains WebRTC nICEr scalars
 # For more info on ICE, see https://tools.ietf.org/html/rfc5245
 # For more info on STUN, see https://tools.ietf.org/html/rfc5389
 # For more info on TURN, see https://tools.ietf.org/html/rfc5766
 webrtc.nicer:
   stun_retransmits:
     bug_numbers:
       - 1325536