Commit 03a506c4 authored by Henrik Boström's avatar Henrik Boström Committed by Commit Bot

Add whitelist preventing additions to legacy getStats() API.

Historically, new stats have bypassed stats OWNERs review and made it to
Chrome stable. This will cause import breakages if stats are added to
the legacy getStats() API in third_party/webrtc assuming:
1. They are present in a normal call setup, i.e. shows up in the
   scenario modelled by:
   WebRtcBrowserTest.RunsAudioVideoWebRTCCallInTwoTabsGetStatsCallback
2. The new stat does not recycle an already existing whitelisted name.

// The run was green except for unrelated failures with
// mac_chromium_rel_ng that have happened on multiple CLs
NOTRY=True

Bug: 822696
Change-Id: I2e6735ae6f1b987eb64865cb510eb65a6a1e4126
Reviewed-on: https://chromium-review.googlesource.com/1146726
Commit-Queue: Henrik Boström <hbos@chromium.org>
Reviewed-by: default avatarHarald Alvestrand <hta@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577178}
parent 12d366cd
...@@ -528,7 +528,8 @@ void WebRtcTestBase::GenerateAndCloneCertificate( ...@@ -528,7 +528,8 @@ void WebRtcTestBase::GenerateAndCloneCertificate(
void WebRtcTestBase::VerifyStatsGeneratedCallback( void WebRtcTestBase::VerifyStatsGeneratedCallback(
content::WebContents* tab) const { content::WebContents* tab) const {
EXPECT_EQ("ok-got-stats", ExecuteJavascript("verifyStatsGenerated()", tab)); EXPECT_EQ("ok-got-stats",
ExecuteJavascript("verifyLegacyStatsGenerated()", tab));
} }
std::vector<std::string> WebRtcTestBase::VerifyStatsGeneratedPromise( std::vector<std::string> WebRtcTestBase::VerifyStatsGeneratedPromise(
......
...@@ -431,12 +431,13 @@ function hasSeenCryptoInSdp() { ...@@ -431,12 +431,13 @@ function hasSeenCryptoInSdp() {
} }
/** /**
* Verifies that the legacy |RTCPeerConnection.getStats| returns stats and * Verifies that the legacy |RTCPeerConnection.getStats| returns stats, that
* verifies that each stats member is a string. * each stats member is a string, and that each stats member is on the
* whitelist.
* *
* Returns ok-got-stats on success. * Returns ok-got-stats on success.
*/ */
function verifyStatsGenerated() { function verifyLegacyStatsGenerated() {
peerConnection_().getStats( peerConnection_().getStats(
function(response) { function(response) {
var reports = response.result(); var reports = response.result();
...@@ -448,6 +449,14 @@ function verifyStatsGenerated() { ...@@ -448,6 +449,14 @@ function verifyStatsGenerated() {
var statValue = reports[i].stat(statNames[j]); var statValue = reports[i].stat(statNames[j]);
if (typeof statValue != 'string') if (typeof statValue != 'string')
throw failTest('A stat was returned that is not a string.'); throw failTest('A stat was returned that is not a string.');
if (!isWhitelistedLegacyStat(statNames[j])) {
throw failTest(
'"' + statNames[j] + '" is not a whitelisted stat. Exposing ' +
'new metrics in the legacy getStats() API is not allowed. ' +
'Please follow the standardization process: ' +
'https://docs.google.com/document/d/1q1CJVUqJ6YW9NNRc0tENkLNn' +
'y8AHrKZfqjy3SL89zjc/edit?usp=sharing');
}
} }
} }
if (numStats === 0) if (numStats === 0)
...@@ -599,3 +608,153 @@ function parseJson_(json) { ...@@ -599,3 +608,153 @@ function parseJson_(json) {
exception); exception);
} }
} }
/**
* The legacy stats API is non-standard. It should be deprecated and removed.
* New stats are not allowed. To add new metrics, follow the standardization
* process, and only add it to the promise-based getStats() API. See:
* https://docs.google.com/document/d/1q1CJVUqJ6YW9NNRc0tENkLNny8AHrKZfqjy3SL89zjc/edit?usp=sharing
* @private
*/
function isWhitelistedLegacyStat(stat) {
const whitelist = new Set([
"aecDivergentFilterFraction",
"audioOutputLevel",
"audioInputLevel",
"bytesSent",
"concealedSamples",
"concealmentEvents",
"packetsSent",
"bytesReceived",
"label",
"packetsReceived",
"packetsLost",
"protocol",
"totalSamplesReceived",
"transportId",
"selectedCandidatePairId",
"ssrc",
"state",
"datachannelid",
"framesDecoded",
"framesEncoded",
"jitterBufferDelay",
"codecImplementationName",
"mediaType",
"qpSum",
"googAccelerateRate",
"googActiveConnection",
"googActualEncBitrate",
"googAvailableReceiveBandwidth",
"googAvailableSendBandwidth",
"googAvgEncodeMs",
"googBucketDelay",
"googBandwidthLimitedResolution",
"requestsSent",
"consentRequestsSent",
"responsesSent",
"requestsReceived",
"responsesReceived",
"stunKeepaliveRequestsSent",
"stunKeepaliveResponsesReceived",
"stunKeepaliveRttTotal",
"stunKeepaliveRttSquaredTotal",
"ipAddress",
"networkType",
"portNumber",
"priority",
"transport",
"candidateType",
"googChannelId",
"googCodecName",
"googComponent",
"googContentName",
"googContentType",
"googCpuLimitedResolution",
"googDecodingCTSG",
"googDecodingCTN",
"googDecodingMuted",
"googDecodingNormal",
"googDecodingPLC",
"googDecodingCNG",
"googDecodingPLCCNG",
"googDerBase64",
"dtlsCipher",
"googEchoCancellationEchoDelayMedian",
"googEchoCancellationEchoDelayStdDev",
"googEchoCancellationReturnLoss",
"googEchoCancellationReturnLossEnhancement",
"googEncodeUsagePercent",
"googExpandRate",
"googFingerprint",
"googFingerprintAlgorithm",
"googFirsReceived",
"googFirsSent",
"googFrameHeightInput",
"googFrameHeightReceived",
"googFrameHeightSent",
"googFrameRateReceived",
"googFrameRateDecoded",
"googFrameRateOutput",
"googDecodeMs",
"googMaxDecodeMs",
"googCurrentDelayMs",
"googTargetDelayMs",
"googJitterBufferMs",
"googMinPlayoutDelayMs",
"googRenderDelayMs",
"googCaptureStartNtpTimeMs",
"googFrameRateInput",
"googFrameRateSent",
"googFrameWidthInput",
"googFrameWidthReceived",
"googFrameWidthSent",
"googHasEnteredLowResolution",
"hugeFramesSent",
"googInitiator",
"googInterframeDelayMax",
"googIssuerId",
"googJitterReceived",
"googLocalAddress",
"localCandidateId",
"googLocalCandidateType",
"localCertificateId",
"googAdaptationChanges",
"googNacksReceived",
"googNacksSent",
"googPreemptiveExpandRate",
"googPlisReceived",
"googPlisSent",
"googPreferredJitterBufferMs",
"googReadable",
"googRemoteAddress",
"remoteCandidateId",
"googRemoteCandidateType",
"remoteCertificateId",
"googResidualEchoLikelihood",
"googResidualEchoLikelihoodRecentMax",
"googAnaBitrateActionCounter",
"googAnaChannelActionCounter",
"googAnaDtxActionCounter",
"googAnaFecActionCounter",
"googAnaFrameLengthIncreaseCounter",
"googAnaFrameLengthDecreaseCounter",
"googAnaUplinkPacketLossFraction",
"googRetransmitBitrate",
"googRtt",
"googSecondaryDecodedRate",
"googSecondaryDiscardedRate",
"packetsDiscardedOnSend",
"googSpeechExpandRate",
"srtpCipher",
"googTargetEncBitrate",
"totalAudioEnergy",
"totalSamplesDuration",
"googTransmitBitrate",
"googTransportType",
"googTrackId",
"googTimingFrameInfo",
"googTypingNoiseState",
"googWritable" ]);
return whitelist.has(stat);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment