Bug 1644709 - Add PeerConnection configuration to about:webrtc;r=dminor,jib,webidl,smaug

Differential Revision: https://phabricator.services.mozilla.com/D80787
This commit is contained in:
Nico Grunbaum 2020-06-30 02:35:36 +00:00
Родитель 00688236a3
Коммит c78d9cccad
7 изменённых файлов: 153 добавлений и 1 удалений

Просмотреть файл

@ -5,6 +5,7 @@
#ifndef _WEBRTC_GLOBAL_H_
#define _WEBRTC_GLOBAL_H_
#include "WebrtcIPCTraits.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/RTCDataChannelBinding.h"
@ -87,6 +88,21 @@ struct ParamTraits<
}
};
template <>
struct ParamTraits<mozilla::dom::RTCBundlePolicy>
: public ContiguousEnumSerializer<
mozilla::dom::RTCBundlePolicy,
mozilla::dom::RTCBundlePolicy::Balanced,
mozilla::dom::RTCBundlePolicy::EndGuard_> {};
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::RTCIceServerInternal, mUrls,
mCredentialProvided, mUserNameProvided);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::RTCConfigurationInternal,
mBundlePolicy, mCertificatesProvided,
mIceServers, mIceTransportPolicy,
mPeerIdentityProvided, mSdpSemantics);
DEFINE_IPC_SERIALIZER_WITH_FIELDS(mozilla::dom::RTCSdpHistoryEntryInternal,
mTimestamp, mIsLocal, mSdp);
@ -101,7 +117,7 @@ DEFINE_IPC_SERIALIZER_WITH_FIELDS(
DEFINE_IPC_SERIALIZER_WITH_SUPER_CLASS_AND_FIELDS(
mozilla::dom::RTCStatsReportInternal, mozilla::dom::RTCStatsCollection,
mClosed, mLocalSdp, mSdpHistory, mPcid, mRemoteSdp, mTimestamp,
mCallDurationMs, mIceRestarts, mIceRollbacks, mOfferer);
mCallDurationMs, mIceRestarts, mIceRollbacks, mOfferer, mConfiguration);
typedef mozilla::dom::RTCStats RTCStats;

Просмотреть файл

@ -199,10 +199,29 @@ dictionary RTCStatsCollection {
sequence<RTCVideoFrameHistoryInternal> videoFrameHistories = [];
};
// Details that about:webrtc can display about configured ICE servers
dictionary RTCIceServerInternal {
sequence<DOMString> urls = [];
required boolean credentialProvided;
required boolean userNameProvided;
};
// Details that about:webrtc can display about the RTCConfiguration
// Chrome only
dictionary RTCConfigurationInternal {
RTCBundlePolicy bundlePolicy;
required boolean certificatesProvided;
sequence<RTCIceServerInternal> iceServers = [];
RTCIceTransportPolicy iceTransportPolicy;
required boolean peerIdentityProvided;
DOMString sdpSemantics;
};
// A collection of RTCStats dictionaries, plus some other info. Used by
// WebrtcGlobalInformation for about:webrtc, and telemetry.
dictionary RTCStatsReportInternal : RTCStatsCollection {
required DOMString pcid;
RTCConfigurationInternal configuration;
DOMString localSdp;
DOMString remoteSdp;
sequence<RTCSdpHistoryEntryInternal> sdpHistory = [];

Просмотреть файл

@ -290,6 +290,7 @@ bool IsPrivateBrowsing(nsPIDOMWindowInner* aWindow) {
PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
: mTimeCard(MOZ_LOG_TEST(logModuleInfo, LogLevel::Error) ? create_timecard()
: nullptr),
mJsConfiguration(),
mSignalingState(RTCSignalingState::Stable),
mIceConnectionState(RTCIceConnectionState::New),
mIceGatheringState(RTCIceGatheringState::New),
@ -389,6 +390,9 @@ nsresult PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
}
CheckThread();
// Store the configuration for about:webrtc
StoreConfigurationForAboutWebrtc(aConfiguration);
mPCObserver = &aObserver;
// Find the STS thread
@ -2791,6 +2795,7 @@ RefPtr<dom::RTCStatsReportPromise> PeerConnectionImpl::GetStats(
UniquePtr<dom::RTCStatsReportInternal> report(
new dom::RTCStatsReportInternal);
report->mPcid = NS_ConvertASCIItoUTF16(mName.c_str());
report->mConfiguration.Construct(mJsConfiguration);
// TODO(bug 1589416): We need to do better here.
if (!mIceStartTime.IsNull()) {
report->mCallDurationMs.Construct(
@ -2925,6 +2930,45 @@ void PeerConnectionImpl::RecordIceRestartStatistics(JsepSdpType type) {
}
}
void PeerConnectionImpl::StoreConfigurationForAboutWebrtc(
const dom::RTCConfiguration& aConfig) {
// This will only be called once, when the PeerConnection is initially
// configured, at least until setConfiguration is implemented
// see https://bugzilla.mozilla.org/show_bug.cgi?id=1253706
// @TODO call this from setConfiguration
if (aConfig.mIceServers.WasPassed()) {
for (const auto& server : aConfig.mIceServers.Value()) {
RTCIceServerInternal internal;
internal.mCredentialProvided = server.mCredential.WasPassed();
internal.mUserNameProvided = server.mUsername.WasPassed();
if (server.mUrl.WasPassed()) {
if (!internal.mUrls.AppendElement(server.mUrl.Value(), fallible)) {
mozalloc_handle_oom(0);
}
}
if (server.mUrls.WasPassed()) {
for (const auto& url : server.mUrls.Value().GetAsStringSequence()) {
if (!internal.mUrls.AppendElement(url, fallible)) {
mozalloc_handle_oom(0);
}
}
}
if (!mJsConfiguration.mIceServers.AppendElement(internal, fallible)) {
mozalloc_handle_oom(0);
}
if (aConfig.mSdpSemantics.WasPassed()) {
mJsConfiguration.mSdpSemantics.Construct(aConfig.mSdpSemantics.Value());
}
}
}
mJsConfiguration.mIceTransportPolicy.Construct(aConfig.mIceTransportPolicy);
mJsConfiguration.mBundlePolicy.Construct(aConfig.mBundlePolicy);
mJsConfiguration.mPeerIdentityProvided = !aConfig.mPeerIdentity.IsEmpty();
mJsConfiguration.mCertificatesProvided =
aConfig.mCertificates.WasPassed() &&
!aConfig.mCertificates.Value().Length();
}
// Telemetry for when calls start
void PeerConnectionImpl::startCallTelem() {
if (mWindow) {

Просмотреть файл

@ -511,11 +511,16 @@ class PeerConnectionImpl final
void RecordIceRestartStatistics(JsepSdpType type);
void StoreConfigurationForAboutWebrtc(const RTCConfiguration& aConfig);
// Timecard used to measure processing time. This should be the first class
// attribute so that we accurately measure the time required to instantiate
// any other attributes of this class.
Timecard* mTimeCard;
// Configuration used to initialize the PeerConnection
dom::RTCConfigurationInternal mJsConfiguration;
mozilla::dom::RTCSignalingState mSignalingState;
// ICE State

Просмотреть файл

@ -88,6 +88,14 @@ html {
border-color: black;
}
.peer-connection-config div {
margin-inline: 1em;
}
.peer-connection-config div:nth-of-type(odd) {
background-color: #ddd;
}
.ice-trickled { background-color: hsla(210, 66%, 75%, 1); }
.ice-success { background-color: hsla(120, 66%, 75%, 1); }
.ice-failed { background-color: hsla(0, 66%, 75%, 1); }

Просмотреть файл

@ -422,6 +422,8 @@ PeerConnection.prototype = {
let div = new FoldableSection(pc).render();
div.appendChild(this.renderDesc());
div.appendChild(this.renderConfiguration());
div.appendChild(new ICEStats(this._report).render());
div.appendChild(new SDPStats(this._report).render());
for (const frameStats of this._report.videoFrameHistories) {
@ -461,6 +463,58 @@ PeerConnection.prototype = {
return info;
},
renderConfiguration() {
const provided = () => {
const italics = document.createElement("i");
italics.textContent = getString("configuration_element_provided");
return italics;
};
const notProvided = () => {
const italics = document.createElement("i");
italics.textContent = getString("configuration_element_not_provided");
return italics;
};
const br = () => document.createElement("br");
const div = document.createElement("div");
div.classList = "peer-connection-config";
// Create the text for a configuration field
const cfg = (obj, key, elem) => {
elem.append(br(), `${key}: `, key in obj ? `${obj[key]}` : notProvided());
};
// Create the text for a fooProvided configuration field
const pro = (obj, key, elem) => {
elem.append(
br(),
`${key}(`,
provided(),
"/",
notProvided(),
"): ",
`${key}Provided` in obj ? provided() : notProvided()
);
};
const c = this._report.configuration;
div.append("RTCConfiguration");
cfg(c, "bundlePolicy", div);
cfg(c, "iceTransportPolicy", div);
pro(c, "peerIdentity", div);
cfg(c, "sdpSemantics", div);
div.append(br(), "iceServers: ");
if (!c.iceServers) {
div.append(notProvided());
}
for (const i of c.iceServers) {
const inner = document.createElement("div");
div.append(inner);
inner.append(`urls: ${JSON.stringify(i.urls)}`);
pro(i, "credential", inner);
pro(i, "userName", inner);
}
return div;
},
getPCInfo(report) {
return {
id: report.pcid.match(/id=(\S+)/)[1],

Просмотреть файл

@ -155,4 +155,10 @@ last_frame_timestamp = Last Frame Reception Timestamp
local_receive_ssrc = Local Receiving SSRC
# This is an SSRC on the remote side of the connection that is sending RTP
remote_send_ssrc = Remote Sending SSRC
# An option whose value will not be displayed but instead noted as having been
# provided
configuration_element_provided = Provided
# An option whose value will not be displayed but instead noted as having not
# been provided
configuration_element_not_provided = Not Provided